2012-12-07 34 views
16

में 3 डी टेक्स्ट प्रभाव मैं अपनी स्क्रीन में से एक पर कुछ पाठ प्रस्तुत करना चाहता हूं जिसमें 3 डीश दिखता है। मैं UIKit और मानक विचारों नियंत्रकों आदिआईओएस

प्रभाव का उपयोग कर रहा कुछ इस तरह दिखेगा:

enter image description here

इस UIKit & iOS के साथ किसी भी तरह से किया जा सकता है? आम तौर पर मैं केवल एक स्थिर पीएनजी का उपयोग करता हूं, पाठ उपयोगकर्ता गतिशील

+0

छाया प्रभाव बहुत बुनियादी है, लेकिन मैं यह भी पता है कि कैसे इस तरह पाठ को बदलने के लिए करना चाहते हैं .. हो सकता है कि एक कस्टम फ़ॉन्ट इसे अपने आप कर सकता है? – rdurand

+0

हाँ छाया सीधे आगे होगी लेकिन यह इस मामले में मैं नहीं चाहता हूं। मुझे नहीं लगता कि कस्टम फोंट इस तरह के प्रतिपादन विवरण निर्दिष्ट करने में सक्षम होंगे। – Imran

+0

क्या आपने छाया संपत्ति और छाया ऑफसेट के साथ प्रयास किया है? – iDev

उत्तर

10

पर आधारित गतिशील और अद्यतन है, निम्न कोड सही नहीं हो सकता है, लेकिन यह एक अच्छा प्रारंभिक बिंदु होना चाहिए।

असल में आप दो बार फ़ॉन्ट खींचते हैं, थोड़ा आकार और ऑफ़सेट बदलते हैं। जिस फ़ॉन्ट और आकार के साथ आप काम कर रहे हैं उसके आधार पर आपको fontSize, fontSizeDelta और fontOffset के साथ थोड़ा सा खेलना होगा।

परिणाम इस तरह कुछ हद तक दिखता है:

enter image description here

- (UIImage *)imageWith3dString:(NSString *)text 
{ 
    CGFloat fontSize = 150.0; 
    CGFloat fontSizeDelta = 3.0; 
    CGFloat fontOffset = 5.0; 

    NSString *fontName = @"Bebas"; 
    UIFont *font = [UIFont fontWithName:fontName size:fontSize]; 
    CGSize textSize = [text sizeWithFont:font 
         constrainedToSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; 

    CGSize size = CGSizeMake(textSize.width, fontSize); 

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef ctx = CGBitmapContextCreate(NULL, 
              (int)size.width, 
              (int)size.height, 
              8, 
              (int)(4 * size.width), 
              colorSpace, 
              kCGImageAlphaPremultipliedLast); 

    // Draw with shadow 
    CGContextSetShadowWithColor(ctx, CGSizeMake(0, 0), 10.0, [UIColor colorWithWhite:0.0 alpha:0.6].CGColor); 

    CGContextSetRGBStrokeColor(ctx, 1.0, 1.0, 1.0, 0.6); 
    CGContextSetAllowsAntialiasing(ctx, YES); 
    CGContextSetLineWidth(ctx, 2.0); 
    CGContextSetTextDrawingMode(ctx, kCGTextFillStroke); 

    CGContextSetRGBFillColor(ctx, 222/255.0, 222/255.0, 222/255.0, 1.0); 
    CGContextSetCharacterSpacing(ctx, 2.6); 
    CGContextSelectFont(ctx, [fontName UTF8String], fontSize - fontSizeDelta, kCGEncodingMacRoman); 
    CGContextShowTextAtPoint(ctx, 0.0, 3.0 + fontOffset, [text UTF8String], text.length); 

    CGContextSetShadowWithColor(ctx, CGSizeZero, 0.0, NULL); // disable shadow 
    CGContextSetCharacterSpacing(ctx, 1.0); 
    CGContextSelectFont(ctx, [fontName UTF8String], fontSize, kCGEncodingMacRoman); 
    CGContextShowTextAtPoint(ctx, 0.0, 3.0, [text UTF8String], text.length); 


    CGImageRef imageRef = CGBitmapContextCreateImage(ctx); 
    UIImage *image = [UIImage imageWithCGImage:imageRef]; 

    CGColorSpaceRelease(colorSpace); 
    CGImageRelease(imageRef); 
    CGContextRelease(ctx); 

    return image; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UIImageView *imageView = [[UIImageView alloc] initWithImage:[self imageWith3dString:@"3"]]; 

    [self.view addSubview:imageView]; 
} 

YMMV

+0

हाय टॉमस, यह बहुत करीब है, मुझे लगता है कि शायद संभवतः सबसे नज़दीकी चीज होने जा रही है। – Imran

+0

जब मैं कोशिश करता हूं तो मेरे लॉग क्रे जाते हैं: मुझे '12 दिसंबर 17:28:01 इमेक -1 डी 3 डी टेक्स्ट [1380] : CGContextSetStyle: अवैध संदर्भ 0x0' और '12 दिसंबर 17:28:01 imac-1 जैसी त्रुटियां मिलती हैं 3 डी टेक्स्ट [1380] : CGContextSetRGBStrokeColor: अमान्य संदर्भ 0x0' कोई मदद? – Undo

+1

मुझे लगता है कि आपके पास Bebas फ़ॉन्ट स्थापित नहीं है। फ़ॉन्ट नाम को कुछ अलग करने की कोशिश करें, जैसे "हेल्वैटिका" –

32

ठीक है, यहाँ इस का मूल नमूना है।

विचार यह है कि आप "गहराई" देखो बनाने के लिए एक एक्स/वाई 1 ऑफसेट के साथ एक ही पाठ के परतों को ऊपर और ऊपर खींचते हैं।

मैं एक UIImage श्रेणी, UIImage + 3 डी बनाएं जिसका नाम जो परीक्षण आप कर सकते हैं हैं:

इस शीर्ष लेख है (ज) फ़ाइल

// 
// UIImage+3D.h 
// 
// Created by Lefteris Haritou on 12/10/12. 
// Feel Free to use this code, but please keep the credits 
// 

#import <UIKit/UIKit.h> 

@interface UIImage (Extensions) 

+ (UIImage *)create3DImageWithText:(NSString *)_text Font:(UIFont*)_font ForegroundColor:(UIColor*)_foregroundColor ShadowColor:(UIColor*)_shadowColor outlineColor:(UIColor*)_outlineColor depth:(int)_depth useShine:(BOOL)_shine; 

@end 

यहाँ कार्यान्वयन है (। मी) फ़ाइल

// 
// UIImage+3D.m 
// 
// Created by Lefteris Haritou on 12/10/12. 
// Feel Free to use this code, but please keep the credits 
// 

#import "UIImage+3D.h" 
#import <CoreText/CoreText.h> 
#import <QuartzCore/QuartzCore.h> 

@implementation UIImage (Extensions) 

+ (UIImage *)create3DImageWithText:(NSString *)_text Font:(UIFont*)_font ForegroundColor:(UIColor*)_foregroundColor ShadowColor:(UIColor*)_shadowColor outlineColor:(UIColor*)_outlineColor depth:(int)_depth useShine:(BOOL)_shine { 

    //calculate the size we will need for our text 
    CGSize expectedSize = [_text sizeWithFont:_font constrainedToSize:CGSizeMake(MAXFLOAT, MAXFLOAT)]; 

    //increase our size, as we will draw in 3d, so we need extra space for 3d depth + shadow with blur 
    expectedSize.height+=_depth+5; 
    expectedSize.width+=_depth+5; 

    UIColor *_newColor; 

    UIGraphicsBeginImageContextWithOptions(expectedSize, NO, [[UIScreen mainScreen] scale]); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    //because we want to do a 3d depth effect, we are going to slightly decrease the color as we move back 
    //so here we are going to create a color array that we will use with required depth levels 
    NSMutableArray *_colorsArray = [[NSMutableArray alloc] initWithCapacity:_depth]; 

    CGFloat *components = (CGFloat *)CGColorGetComponents(_foregroundColor.CGColor); 

    //add as a first color in our array the original color 
    [_colorsArray insertObject:_foregroundColor atIndex:0]; 

    //create a gradient of our color (darkening in the depth) 
    int _colorStepSize = floor(100/_depth); 

    for (int i=0; i<_depth; i++) { 

     for (int k=0; k<3; k++) { 
      if (components[k]>(_colorStepSize/255.f)) { 
       components[k]-=(_colorStepSize/255.f); 
      } 
     } 
     _newColor = [UIColor colorWithRed:components[0] green:components[1] blue:components[2] alpha:CGColorGetAlpha(_foregroundColor.CGColor)]; 

     //we are inserting always at first index as we want this array of colors to be reversed (darkest color being the last) 
     [_colorsArray insertObject:_newColor atIndex:0]; 
    } 

    //we will draw repeated copies of our text, with the outline color and foreground color, starting from the deepest 
    for (int i=0; i<_depth; i++) { 

     //change color 
     _newColor = (UIColor*)[_colorsArray objectAtIndex:i]; 

     //draw the text 
     CGContextSaveGState(context); 

     CGContextSetShouldAntialias(context, YES); 

     //draw outline if this is the last layer (front one) 
     if (i+1==_depth) { 
      CGContextSetLineWidth(context, 1); 
      CGContextSetLineJoin(context, kCGLineJoinRound); 

      CGContextSetTextDrawingMode(context, kCGTextStroke); 
      [_outlineColor set]; 
      [_text drawAtPoint:CGPointMake(i, i) withFont:_font]; 
     } 

     //draw filling 
     [_newColor set]; 

     CGContextSetTextDrawingMode(context, kCGTextFill); 

     //if this is the last layer (first one we draw), add the drop shadow too and the outline 
     if (i==0) { 
      CGContextSetShadowWithColor(context, CGSizeMake(-2, -2), 4.0f, _shadowColor.CGColor); 
     } 
     else if (i+1!=_depth){ 
      //add glow like blur 
      CGContextSetShadowWithColor(context, CGSizeMake(-1, -1), 3.0f, _newColor.CGColor); 
     } 

     [_text drawAtPoint:CGPointMake(i, i) withFont:_font];   
     CGContextRestoreGState(context); 
    } 

    //if we need to apply the shine 
    if (_shine) { 
     //create an alpha mask from the top most layer of the image, so we can add a shine effect over it 
     CGColorSpaceRef genericRGBColorspace = CGColorSpaceCreateDeviceRGB(); 
     CGContextRef imageContext = CGBitmapContextCreate(NULL, (int)expectedSize.width, (int)expectedSize.height, 8, (int)expectedSize.width * 4, genericRGBColorspace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
     UIGraphicsPushContext(imageContext); 
     CGContextSetTextDrawingMode(imageContext, kCGTextFill); 
     [_text drawAtPoint:CGPointMake(_depth-1, _depth-1) withFont:_font]; 
     CGImageRef alphaMask = CGBitmapContextCreateImage(imageContext); 
     CGContextRelease(imageContext); 
     UIGraphicsPopContext(); 

     //draw shine effect 
     //clip context to the mask we created 
     CGRect drawRect = CGRectZero; 
     drawRect.size = expectedSize; 
     CGContextSaveGState(context); 
     CGContextClipToMask(context, drawRect, alphaMask); 

     CGContextSetBlendMode(context, kCGBlendModeLuminosity); 

     size_t num_locations = 4; 
     CGFloat locations[4] = { 0.0, 0.4, 0.6, 1}; 
     CGFloat gradientComponents[16] = { 
      0.0, 0.0, 0.0, 1.0, 
      0.6, 0.6, 0.6, 1.0, 
      0.8, 0.8, 0.8, 1.0, 
      0.0, 0.0, 0.0, 1.0 
     }; 

     CGGradientRef glossGradient = CGGradientCreateWithColorComponents(genericRGBColorspace, gradientComponents, locations, num_locations); 
     CGPoint start = CGPointMake(0, 0); 
     CGPoint end = CGPointMake(0, expectedSize.height); 
     CGContextDrawLinearGradient(context, glossGradient, start, end, 0); 

     CGColorSpaceRelease(genericRGBColorspace); 
     CGGradientRelease(glossGradient); 
     CGImageRelease(alphaMask); 
     CGContextRestoreGState(context); 
    } 

    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return finalImage; 
} 


@end 

और यह उपयोग करने के लिए, बस श्रेणी एक्सटेंशन आयात तो इसका इस्तेमाल इस प्रकार है:

UIImage *my3dImage = [UIImage create3DImageWithText:@"3" Font:[UIFont systemFontOfSize:250] ForegroundColor:[UIColor colorWithRed:(200/255.f) green:(200/255.f) blue:(200/255.f) alpha:1.0] ShadowColor:[UIColor blackColor] outlineColor:[UIColor colorWithRed:(225/255.f) green:(225/255.f) blue:(225/255.f) alpha:1.0] depth:8 useShine:NO]; 
UIImageView *imgView = [[UIImageView alloc] initWithImage:my3dImage]; 
[self.view addSubview: imgView]; 

enter image description here

एक और उदाहरण यह है:

UIImage *my3dImage = [UIImage create3DImageWithText:@"3D" Font:[UIFont fontWithName:@"MarkerFelt-Wide" size:180] ForegroundColor:[UIColor colorWithRed:(222/255.f) green:(100/255.f) blue:(100/255.f) alpha:1.0] ShadowColor:[UIColor blackColor] outlineColor:[UIColor colorWithRed:(216/255.f) green:(120/255.f) blue:(120/255.f) alpha:1.0] depth:6 useShine:NO]; 
UIImageView *imgView = [[UIImageView alloc] initWithImage:my3dImage]; 
imgView.center = self.view.center; 
[self.view addSubview: imgView]; 

और परिणाम इस प्रकार है:

enter image description here

मैं जोड़ने के लिए कोड संपादित एक चमकदार effe छवि है, जो मेरा मानना ​​है कि बनाता है अधिक सीटी यह देखने के लिए कूलर

UIImage *my3dImage = [UIImage create3DImageWithText:@"3D" Font:[UIFont fontWithName:@"MarkerFelt-Wide" size:180] ForegroundColor:[UIColor colorWithRed:(222/255.f) green:(100/255.f) blue:(100/255.f) alpha:1.0] ShadowColor:[UIColor blackColor] outlineColor:[UIColor colorWithRed:(216/255.f) green:(120/255.f) blue:(120/255.f) alpha:1.0] depth:6 useShine:YES]; 
UIImageView *imgView = [[UIImageView alloc] initWithImage:my3dImage]; 
imgView.center = self.view.center; 
[self.view addSubview: imgView]; 

enter image description here

+2

यह अच्छा, बढ़िया काम दिखता है! – rdurand

+0

मैन .. cool..really cooooool ... – Krishnabhadra

+0

@Lefteris: बस यह विचार मिला: शायद आपको 3 डी की "दिशा" चुनने की क्षमता देनी चाहिए। उदाहरण के लिए, केवल "जाओ" नीचे, या बाएं और ऊपर, आदि देखें। मेरा क्या मतलब है? एक बेहतर उदाहरण के लिए, प्रश्न में, 3 डी प्रभाव केवल नीचे चला जाता है, जबकि आपके उत्तर में यह नीचे और दाएं हो जाता है। मुझे नहीं लगता कि यह आपके कोड में शामिल करना मुश्किल है (जब आप * UIViewAnimationCurveEaseInOut * का उपयोग करते हैं तो उपयोगकर्ता को एन्म के साथ विधि कॉल में पैरामीटर के रूप में पास करने दें) और यह बहुत अच्छा हो सकता है! मुझे लगता है कि आपको निश्चित रूप से इसे cocoacontrols.com पर भेजना चाहिए! – rdurand