I'm trying to add a text to an UIImage and I'm getting a pixelated drawing.
I have tried some other answers with no success:
Drawing on the retina display using CoreGraphics - Image pixelated
Retina display core graphics font quality
Drawing with Core Graphics looks chunky on Retina display
My code:
-(UIImage *)addText:(UIImage *)imgV text:(NSString *)text1
{
int w = self.frame.size.width * 2;
int h = self.frame.size.height * 2;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate
(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), imgV.CGImage);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1);
char* text = (char *)[text1 cStringUsingEncoding:NSASCIIStringEncoding];
CGContextSelectFont(context, "Arial", 24, kCGEncodingMacRoman);
// Adjust text;
CGContextSetTextDrawingMode(context, kCGTextInvisible);
CGContextShowTextAtPoint(context, 0, 0, text, strlen(text));
CGPoint pt = CGContextGetTextPosition(context);
float posx = (w/2 - pt.x)/2.0;
float posy = 54.0;
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetRGBFillColor(context, 255, 255, 255, 1.0);
CGContextShowTextAtPoint(context, posx, posy, text, strlen(text));
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return [UIImage imageWithCGImage:imageMasked];
}
Like Peter said, use UIGraphicsBeginImageContextWithOptions. You might want to pass image.scale to the scale attribute (where image.scale is the scale of one of the images you're drawing), or simply use [UIScreen mainScreen].scale.
This code can be made simpler overall. Try something like:
// Create the image context
UIGraphicsBeginImageContextWithOptions(_baseImage.size, NO, _baseImage.scale);
// Draw the image
CGRect rect = CGRectMake(0, 0, _baseImage.size.width, _baseImage.size.height);
[_baseImage drawInRect:rect];
// Get a vertically centered rect for the text drawing
rect.origin.y = (rect.size.height - FONT_SIZE) / 2 - 2;
rect = CGRectIntegral(rect);
rect.size.height = FONT_SIZE;
// Draw the text
UIFont *font = [UIFont boldSystemFontOfSize:FONT_SIZE];
[[UIColor whiteColor] set];
[text drawInRect:rect withFont:font lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter];
// Get and return the new image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
Where text is an NSString object.
I was facing the exact same problem and posted a question last night to which no-one replied. I have combined fnf's suggested changes with Clif Viegas's answer in the following question:
CGContextDrawImage draws image upside down when passed UIImage.CGImage
to come up with the solution. My addText method is slightly different from yours:
+(UIImage *)addTextToImage:(UIImage *)img text:(NSString *)text1{
int w = img.size.width;
int h = img.size.height;
CGSize size = CGSizeMake(w, h);
if (UIGraphicsBeginImageContextWithOptions != NULL) {
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
} else {
UIGraphicsBeginImageContext(size);
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0,h);
CGContextScaleCTM(context, 1.0, -1.0);
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, "Times New Roman", 14, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetRGBFillColor(context, 0, 0, 0, 1);
//rotate text
CGContextSetTextMatrix(context, CGAffineTransformMakeRotation( -M_PI/8 ));
CGContextShowTextAtPoint(context, 70, 88, text, strlen(text));
CGColorSpaceRelease(colorSpace);
UIGraphicsEndImageContext();
return newImg;
}
In summary, what I have done is add
if (UIGraphicsBeginImageContextWithOptions != NULL) {
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
} else {
UIGraphicsBeginImageContext(size);
}
Remove
// CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
and put
CGContextRef context = UIGraphicsGetCurrentContext();
instead. But this causes the image to be upside down. Hence I put
CGContextTranslateCTM(context, 0,h);
CGContextScaleCTM(context, 1.0, -1.0);
just before
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
This way you can use CG functions instead of using drawInRect etc.
Don't forget
UIGraphicsEndImageContext
at the end. Hope this helps.
Related
I just want to put the current geolocation on a photo taken from my iPhone/iPad.Is this possible?I have already got the geolocation but can I edit the photo programmatically by adding a text label over it.
Thanks for any help.
You can add text on image using :
//Add text to UIImage
-(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];
}
Hope it helps you.
here is the sample method which will return you a image with text on it
-(UIImage*) getImageWithText:(UIImage*) sourceImage
{
UIGraphicsBeginImageContext(sourceImage.size);
[sourceImage drawAtPoint:CGPointZero];
[#"someText" drawAtPoint:CGPointMake(x,y) [UIFont systemFontOfSize:14]]
UIImage* imageWithText = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageWithText;
}
I want to create UIImage of text.Is there any tutorial of something which could help me.I read many blog but all the blogs showing that how to create text on uiimage but I need uimage of written text. If somebody have any idea about this , please help me.Thank you very much.
hi you try this this....
i hope it will work for you
-(UIImage *)imageFromText:(NSString *)text withImage:(UIImage*)img{
// set the font type and size
UIFont *font = [UIFont systemFontOfSize:100.0];
CGSize size = [text sizeWithFont:font];
// check if UIGraphicsBeginImageContextWithOptions is available (iOS is 4.0+)
if (UIGraphicsBeginImageContextWithOptions != NULL)
UIGraphicsBeginImageContextWithOptions(size,NO,0.0);
else
// iOS is < 4.0
UIGraphicsBeginImageContext(size);
// optional: add a shadow, to avoid clipping the shadow you should make the context size bigger
//
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetShadowWithColor(ctx, CGSizeMake(0.0, 1.0), 5.0, [[UIColor blackColor] CGColor]);
CGContextSetBlendMode(ctx,kCGBlendModeNormal);
// CGContextSetFillColorWithColor(ctx, [UIColor whiteColor].CGColor);
CGContextSetFillColorWithColor(ctx, [UIColor colorWithPatternImage:img].CGColor);
/*NSLog(#"Rect %#",CGContextGetClipBoundingBox(ctx));
CGImageRef alphaMask = CGBitmapContextCreateImage(ctx);
CGContextClipToMask(ctx, CGContextGetClipBoundingBox(ctx), alphaMask);*/
// draw in context, you can use also drawInRect:withFont:
[text drawAtPoint:CGPointMake(0.0, 0.0) withFont:font];
// transfer image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
the method call will be...
[self imageFromText:#"Booooooooom"];
Check this snippet of code, should work. You can freely change some of the parameters within function. Note that you must pass UIImage created somewhere else to this method.
//Add text to UIImage
-(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'm creating an image by combining two other images, using CGContext. Even if I have the #2x images, I can't succeed to create an retina image.
Here's my code. Could you please help ?
-(UIImage*)makePinImageWithImage:(UIImage*)icon {
UIImage * pin = [UIImage imageNamed:#"defaultPin.png"]; // I have the #2x one.
int w = pin.size.width;
int h = pin.size.height;
CGRect iconRect = CGRectMake(16, 47, 24, 26); // the frame where mix icon in pin
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 8 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
// Drawing pin in context
CGContextDrawImage(context, CGRectMake(0, 0, w, h), pin.CGImage);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1);
// Drawing icon in context
CGContextDrawImage(context, iconRect, icon.CGImage);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1);
// Getting back the final image
CGImageRef imageCG = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
UIImage * createdImage = [UIImage imageWithCGImage:imageCG];
CGImageRelease(imageCG);
return createdImage;
}
Thanks
This code is done in a text window, should more or less do what you want.
(UIImage*)makePinImageWithImage:(UIImage*)icon // this code assumes this image is #2x if the device is
{
UIImage *pin = [UIImage imageNamed:#"defaultPin.png"]; // I have the #2x one.
CGFloat w = rintf(pin.size.width);
CGFloat h = rintf(pin.size.height);
UIGraphicsBeginImageContextWithOptions(CGSizeMake(w, h), YES, 0); // 0 means let iOS deal with scale for you
CGContextRef context = UIGraphicsGetCurrentContext();
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, h);
CGContextConcatCTM(context, flipVertical);
CGRect iconRect = CGRectMake(16, 47, 24, 26); // the frame where mix icon in pin
// Drawing pin in context
CGContextDrawImage(context, CGRectMake(0, 0, w, h), [pin CGImage]); // CGImage is a method, not a property
//CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1); // this does not do anything does it? You never do a FillRect...
// Drawing icon in context
CGContextDrawImage(context, iconRect, [icon CGImage]);
//CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1); // this does not do anything does it? You never do a FillRect...
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image; // will be either normally sized or retina sized depending on environment
}
This code is not working and i do not understand the mistake.
Please help.
-(UIImage *)addText:(UIImage *)img text:(NSString *)text1
{
int w = img.size.width;
int h = img.size.height;
//lon = h - lon;
char* text = (char *)[text1 cStringUsingEncoding:NSASCIIStringEncoding];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
/*UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
CGContextShowTextAtPoint(UIGraphicsGetCurrentContext(), 50, 100, text, strlen(text));
UIImage *viewImage =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSLog(#"View Image : %#",viewImage);*/
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
CGContextShowTextAtPoint(context, 0, 50, text, strlen(text));
CGContextSetTextMatrix(context, CGAffineTransformMakeRotation( -M_PI/4 ));
CGContextShowTextAtPoint(context, 50, 100, text, strlen(text));
//UIImage *compositeImage = UIGraphicsGetImageFromCurrentImageContext();
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
NSLog(#"Image : %#",[UIImage imageWithCGImage:imageMasked]);
return [UIImage imageWithCGImage:imageMasked];
//return viewImage;
}
Unless you have a reason to avoid NSString UIKit additions, this will suffice:
+(UIImage*) drawText:(NSString*) text
inImage:(UIImage*) image
atPoint:(CGPoint) point
font:(UIFont*) font
color:(UIColor*) color
{
UIGraphicsBeginImageContextWithOptions(image.size, FALSE, 0.0);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(point.x, point.y, image.size.width, image.size.height);
[color set];
[text drawInRect:CGRectIntegral(rect) withFont:font];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Your code does work.
Make sure the string you are passing into it is not empty.
I want to add watermarks on an UIImage.
For that i have googled and also studied questions on this website like this
But did not get any help.
Just add image on your image view and then add one subview on it and set alpha of subview less so it look like water mark or you can add label, but in label you have to change its angel to show angular
If your UIImage is suppose in the imageview and watermark image in the imageview1, then use method of UIView class
[imageview addSubview: imageview1];
.
Try this
//get image width and height
int w = img.size.width;
int h = img.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//create a graphic context with CGBitmapContextCreate
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
CGContextSetRGBFillColor(context, 0.0, 1.0, 1.0, 1);
char* text = (char *)[text1 cStringUsingEncoding:NSASCIIStringEncoding];
CGContextSelectFont(context, "Georgia", 30, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetRGBFillColor(context, 255, 0, 0, 1);
CGContextSetTextMatrix(context, CGAffineTransformMakeRotation( -M_PI/4 ));
CGContextShowTextAtPoint(context, 40, 20, text, strlen(text));
//Create image ref from the context
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return [UIImage imageWithCGImage:imageMasked];