as CGContextShowTextAtPoint is deprecated in iOS 7, i would like to change CGContextShowTextAtPoint to drawAtPoint but the text is outputting.
//Add text to UIImage
-(UIImage *)addText:(UIImage *)img text:(NSString *)text1{
int w = 32;
int h = 32;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
//char* text= (char *)[text1 cStringUsingEncoding:NSASCIIStringEncoding];
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetRGBFillColor(context, 0, 0, 0, 1);
// CGContextSelectFont(context, "Montserrat-Regular",12, kCGEncodingMacRoman);
// CGContextShowTextAtPoint(context,9,12,text, strlen(text));
//
[text1 drawAtPoint:CGPointMake(0, 0) withFont:[UIFont fontWithName:#"Montserrat-Regular" size:12]];
CGImageRef imgCombined = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
UIImage *retImage = [UIImage imageWithCGImage:imgCombined];
CGImageRelease(imgCombined);
return retImage;
}
ok got it work on
//Add text to UIImage
-(UIImage *)addText:(UIImage *)img text:(NSString *)text1
{
UIGraphicsBeginImageContext(CGSizeMake(36, 36));
CGRect aRectangle = CGRectMake(0,0, 36.0f,36.0f);
[img drawInRect:aRectangle];
[text1 drawInRect : CGRectMake(0, 10, 36, 36)
withFont : [UIFont fontWithName:#"Montserrat-Regular" size:12]
lineBreakMode : NSLineBreakByTruncatingTail
alignment : NSTextAlignmentCenter ];
UIImage *theImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return theImage;
}
Related
I have some problem with UISegmentedControl with image. When I put image with text on it in segment tintcolor paints my image and the text.
Can any help with it?
setting up UIImage in Segment
UIImage *tmp = [UIImage imageNamed:#"UISegmentedControl-active"];
UIImage *imageWithText = [UIImage imageFromImage:tmp string:#"20" color:[UIColor whiteColor]];
[self.segmentedControl setImage:imageWithText forSegmentAtIndex:0];
imageFromImage code:
+ (id) imageFromImage:(UIImage*)image string:(NSString*)string color:(UIColor*)color
{
UIFont *font = [UIFont systemFontOfSize:16.0];
CGSize expectedTextSize = [string sizeWithAttributes:#{NSFontAttributeName: font}];
int width = image.size.width + 5;
int height = MAX(expectedTextSize.height, image.size.width);
CGSize size = CGSizeMake((float)width, (float)height);
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
int fontTopPosition = (height - expectedTextSize.height) / 2;
CGPoint textPoint = CGPointMake(width + 5, fontTopPosition);
// Images upside down so flip them
//CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, size.height);
//CGContextConcatCTM(context, flipVertical);
CGContextDrawImage(context, (CGRect){ {0, (height - image.size.height) / 2}, {image.size.width, image.size.height} }, [image CGImage]);
[string drawAtPoint:textPoint withAttributes:#{NSFontAttributeName: font}];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Image goes blue(default tintcolor).
Anyway, if anyone know how to do segmented control with circular(not rounded) segments(buttons), offer your solution.
In my app I'm trying to add a text on an image. I've done it using a post in stackoverflow. It's like the following.
+(UIImage *)addText:(UIImage *)img text:(NSString *)text1{
int w = img.size.width;
int h = img.size.height;
//lon = h - lon;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1);
char* text = (char *)[text1 cStringUsingEncoding:NSASCIIStringEncoding];// "05/05/09";
CGContextSelectFont(context, "Arial", 18, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetRGBFillColor(context, 255, 255, 255, 1);
//rotate text
CGContextSetTextMatrix(context, CGAffineTransformMakeRotation( -M_PI/4 ));
CGContextShowTextAtPoint(context, 4, 52, text, strlen(text));
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return [UIImage imageWithCGImage:imageMasked];
}
When I'm writing a text using this code, the original image's colour is changed like the following,
Original Image
Output with Text
Can anyone explain why is this happening. and how to fix this??
Thanks in Advance!!
We need to create a image context and apply drawing and get final image from this context. You can try this method. Hope this help you.
+ (UIImage *) addText:(UIImage *)img text:(NSString *)text
{
CGRect rect = [[UIScreen mainScreen] bounds];
// create a context according to image size
UIGraphicsBeginImageContext(rect.size);
// draw image
[img drawInRect:rect];
UIFont* font = [UIFont systemFontOfSize:14.0];
/// Make a copy of the default paragraph style
NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
/// Set line break mode
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
/// Set text alignment
paragraphStyle.alignment = NSTextAlignmentCenter;
NSDictionary *attributes = #{ NSFontAttributeName: font,
NSParagraphStyleAttributeName: paragraphStyle };
CGRect textRect = CGRectMake(20, 160.0, 280.0, 44);
/// draw text
[text drawInRect:textRect withAttributes:attributes];
// get as image
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
EDIT: This can only be run on the main thread! So it's pretty much useless.
+(UIImage *)imageFromView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Here's a new one using Core Graphics that can be used on any thread
+ (UIImage *)imageFromView:(UIView *)view
{
size_t width = view.bounds.size.width*2;
size_t height = view.bounds.size.height*2;
unsigned char *imageBuffer = (unsigned char *)malloc(width*height*8);
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef imageContext = CGBitmapContextCreate(imageBuffer, width, height, 8, width*4, colourSpace,kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colourSpace);
CGContextTranslateCTM(imageContext, 0.0, height);
CGContextScaleCTM(imageContext, 2.0, -2.0);
[view.layer renderInContext:imageContext];
CGImageRef outputImage = CGBitmapContextCreateImage(imageContext);
UIImage *image = [[UIImage alloc] initWithCGImage:outputImage];
CGImageRelease(outputImage);
CGContextRelease(imageContext);
free(imageBuffer);
return image;
}
I am using this and it works fine for me
- (UIImage*) drawText:(NSString*) text
inImage:(UIImage*) image
atPoint:(CGPoint) point
{
UIFont *font = [UIFont fontWithName:FONT_BOLD size:20];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(point.x, point.y, image.size.width, image.size.height);
[UIColorFromRGB(0x515151) set];
[text drawInRect:CGRectIntegral(rect) withFont:font];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
I tried to overlay text as a texture using following code snippet:
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 30)];
myLabel.text = #"Hello world!";
myLabel.font = [UIFont fontWithName:#"Helvetica" size:18];
myLabel.textColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:1];
myLabel.backgroundColor = [UIColor clearColor];
UIGraphicsBeginImageContext(myLabel.bounds.size);
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, 30);
CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
[myLabel.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *layerImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
But it's not visible. For displaying image as a texture using OpenGL I tried the following code snippet:
/// here image is the layerImage created in above piece of code
GLuint width = CGImageGetWidth(image.CGImage);
GLuint height = CGImageGetHeight(image.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc( height * width * 4 );
CGContextRef context = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGColorSpaceRelease( colorSpace );
CGContextClearRect( context, CGRectMake( 0, 0, width, height ) );
CGContextTranslateCTM( context, 0, height - height );
CGContextDrawImage( context, CGRectMake( 0, 0, width, height ), image.CGImage );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
CGContextRelease(context);
free(imageData);
[image release];
[texData release];
But the image is not getting displayed. Is there any other approach to display text as a texture using OpenGL in ios?
Need to take photo from the application with date and time the photo has been taken to be displayed in photo just like digital camera.
-(UIImage *)addText:(UIImage *)img text:(NSString *)text1;
{
int w = img.size.width;
int h = img.size.height;
//lon = h - lon;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1);
char* text = (char *)[text1 cStringUsingEncoding:NSASCIIStringEncoding];// "05/05/09";
CGContextSelectFont(context, "Arial", 18, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetRGBFillColor(context, 255, 255, 255, 1);
//rotate text
CGContextSetTextMatrix(context, CGAffineTransformMakeRotation( -M_PI/4 ));
CGContextShowTextAtPoint(context, 4, 52, text, strlen(text));
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return [UIImage imageWithCGImage:imageMasked];
}
I want to draw text on an image. I've tried using CGContextShowTextAtPoint and NSString drawAtPoint, but they both fail to show text with accented characters (i.e. if the text is in French). Basically I want to be able to show unicode characters. Any hints/solutions?
My solution with Core-Graphics (UIImage category method):
- (UIImage *)overlayText:(NSString *)overlayText withFontName:(NSString *)fontName andFontSize:(CGFloat)fontSize {
// Refererence:
// http://iphonesdksnippets.com/post/2009/05/05/Add-text-to-image-%28UIImage%29.aspx
int w = self.size.width;
int h = self.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), self.CGImage);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1);
char *charText = (char *)[overlayText cStringUsingEncoding:NSASCIIStringEncoding];
char *charFontName = (char *)[fontName cStringUsingEncoding:NSASCIIStringEncoding];
CGContextSelectFont(context, charFontName, fontSize, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetRGBFillColor(context, 255, 255, 255, 1);
// rotate text
// CGContextSetTextMatrix(context, CGAffineTransformMakeRotation(-M_PI / 4));
CGFloat textWidth = [overlayText calculateCGTextWidthWithFont:charFontName size:fontSize];
CGFloat xTextPosition = MAX(10.0, w - textWidth - 10.0); // 10.0 inset
CGFloat yTextPosition = 10.0;
CGContextShowTextAtPoint(context, xTextPosition, yTextPosition, charText, strlen(charText));
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return [UIImage imageWithCGImage:imageMasked];
}
My solution with NSString (UIImage category method):
- (UIImage *)overlayText:(NSString *)overlayText withFontName:(NSString *)fontName andFontSize:(CGFloat)fontSize {
UIFont *font = [UIFont fontWithName:fontName size:fontSize];
char *charFontName = (char *)[fontName cStringUsingEncoding:NSASCIIStringEncoding];
CGFloat textWidth = [overlayText calculateCGTextWidthWithFont:charFontName size:fontSize];
CGFloat xTextPosition = MAX(10.0, self.size.width - textWidth - 10.0); // 10.0 margin/inset
CGFloat yTextPosition = self.size.height - fontSize - 10.0; // 10.0 margin/inset
UIGraphicsBeginImageContext(self.size);
[self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
[[UIColor whiteColor] set];
[overlayText drawAtPoint:CGPointMake(xTextPosition, yTextPosition) withFont:font];
UIImage *overlayTextImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return overlayTextImage;
}
My solution with Core-Text (UIImage category method):
- (UIImage *)overlayText:(NSString *)overlayText withFontName:(NSString *)fontName andFontSize:(CGFloat)fontSize {
char *charFontName = (char *)[fontName cStringUsingEncoding:NSASCIIStringEncoding];
CGFloat textWidth = [overlayText calculateCGTextWidthWithFont:charFontName size:fontSize];
CGFloat xTextPosition = 10.0; // MAX(10.0, self.size.width - textWidth - 10.0); // 10.0 margin/inset
CGFloat yTextPosition = self.size.height - fontSize - 10.0; // 10.0 margin/inset
UIGraphicsBeginImageContext(self.size);
[self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
// flip the coordinate system
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// create an attributed string
CFMutableAttributedStringRef attributedOverlayText = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
if (overlayText != nil)
CFAttributedStringReplaceString(attributedOverlayText, CFRangeMake(0, 0), (CFStringRef)overlayText);
CFAttributedStringSetAttribute(attributedOverlayText, CFRangeMake(0, CFAttributedStringGetLength(attributedOverlayText)), kCTForegroundColorAttributeName, [[UIColor whiteColor] CGColor]);
CTFontRef ctFont = CTFontCreateWithName((CFStringRef)fontName, fontSize, NULL);
CFAttributedStringSetAttribute(attributedOverlayText, CFRangeMake(0, CFAttributedStringGetLength(attributedOverlayText)), kCTFontAttributeName, ctFont);
CFRelease(ctFont);
// draw attributed string using CTLineDraw
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attributedOverlayText);
CGContextSetTextPosition(context, xTextPosition, yTextPosition);
CTLineDraw(line, context);
UIImage *overlayTextImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return overlayTextImage;
}
I problem with the above solution is that I'm essentially not getting the proper "width" for the text.
Here's the solution that worked for me (using Core Text):
- (UIImage *)overlayText:(NSString *)overlayText withFontName:(NSString *)fontName andFontSize:(CGFloat)fontSize {
// Develope's Note:
// Problem with implementing a solution using CG is that it doesn't support unicode character drawing i.e French
// Begin new image context
UIGraphicsBeginImageContext(self.size);
// Draw image
[self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
// Flip the coordinate system
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Create an attributed string
CFMutableAttributedStringRef attributedOverlayText = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
if (overlayText != nil)
CFAttributedStringReplaceString(attributedOverlayText, CFRangeMake(0, 0), (__bridge CFStringRef)overlayText);
// Set text color
CFAttributedStringSetAttribute(attributedOverlayText,
CFRangeMake(0, CFAttributedStringGetLength(attributedOverlayText)),
kCTForegroundColorAttributeName,
[[UIColor whiteColor] CGColor]);
// Set text font
CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef)fontName, fontSize, NULL);
CFAttributedStringSetAttribute(attributedOverlayText,
CFRangeMake(0, CFAttributedStringGetLength(attributedOverlayText)),
kCTFontAttributeName,
ctFont);
CFRelease(ctFont);
// Set text alignment (paragraph style)
CTTextAlignment alignment = kCTRightTextAlignment;
CTParagraphStyleSetting settings[] = {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));
CFAttributedStringSetAttribute(attributedOverlayText,
CFRangeMake(0, CFAttributedStringGetLength(attributedOverlayText)),
kCTParagraphStyleAttributeName,
paragraphStyle);
CFRelease(paragraphStyle);
// Create framesetter with the attributed text
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attributedOverlayText);
CFRange stringRange = CFRangeMake(0, CFAttributedStringGetLength(attributedOverlayText));
CGSize fitRange = CTFramesetterSuggestFrameSizeWithConstraints(framesetter,
CFRangeMake(0, 0),
NULL,
CGSizeMake(self.size.width - (2 * 10.0), CGFLOAT_MAX),
NULL);
// Developer's Note:
// We can't use fontSize for the framesetter's height.
// We can't use fitRange.height in the bounding rectangle, because then we won't get the correct text alignment
// Calculate the width (and correspondingly the xTextPosition)
CGRect boundingRect = CGRectMake(10.0,
10.0,
self.size.width - (2 * 10.0),
fitRange.height);
CGMutablePathRef boundingPath = CGPathCreateMutable();
CGPathAddRect(boundingPath, NULL, boundingRect);
// Draw attributed text using CTFrameDraw
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, stringRange, boundingPath, NULL);
CTFrameDraw(frame, context);
CFRelease(framesetter);
// Draw boundary (debugging purposes only)
if (NO) {
// Inner boundary
CGContextSetStrokeColorWithColor(context, [UIColor yellowColor].CGColor);
CGContextSetLineWidth(context, 2.0);
CGContextStrokeRect(context, CGPathGetBoundingBox(boundingPath));
// Outer boundary
CGMutablePathRef controlBoundaryPath = CGPathCreateMutable();
CGPathAddRect(controlBoundaryPath, NULL, CGRectMake(0, 0, self.size.width, self.size.height));
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, 2.0);
CGContextStrokeRect(context, CGPathGetBoundingBox(controlBoundaryPath));
CFRelease(controlBoundaryPath);
}
// Draw attributed string using CTLineDraw
// (Doesn't work if we want to right align the text)
// CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attributedOverlayText);
// CGContextSetTextPosition(context, xTextPosition, yTextPosition);
// CTLineDraw(line, context);
UIImage *overlayTextImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return overlayTextImage;
}
Hope this helps someone.