I want to add text on an image programmatically, but I can't seem to find how to do it. I've found one solution on here, but a lot of things are deprecated so it doesn't work...
Please help!
EDIT:
Here's my code:
UIImage *backgroundImage = image;
NSMutableDictionary *stringAttributes = [NSMutableDictionary dictionary];
[stringAttributes setObject: [UIFont fontWithName:#"Helvetica" size:20] forKey: NSFontAttributeName];
[stringAttributes setObject: [UIColor whiteColor] forKey: NSForegroundColorAttributeName];
[stringAttributes setObject: [NSNumber numberWithFloat: 2.0] forKey: NSStrokeWidthAttributeName];
[stringAttributes setObject: [UIColor blackColor] forKey: NSStrokeColorAttributeName];
[backgroundImage drawInRect:CGRectMake(0, 0, backgroundImage.size.width, backgroundImage.size.height)];
NSString *myString = [NSString stringWithFormat:#"Yolo"];
[myString drawInRect:CGRectMake(0, 0, 200, 50) withAttributes:stringAttributes];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.imageView.image = result;
NEW EDIT:
I'd like to clearify some things to understand the question better. My app lets the user send a photo that they have taken themselves via text messaging or by email, and I want to add some pre-written text from strings, on the photo.
So my question is: How do I get the text from the strings, on to the photo?
It took forever, but I figured it out.
Code:
NSMutableDictionary *stringAttributes = [NSMutableDictionary dictionary];
[stringAttributes setObject: [UIFont fontWithName:#"Avenir Book" size:250] forKey: NSFontAttributeName];
[stringAttributes setObject: [UIColor whiteColor] forKey: NSForegroundColorAttributeName];
NSString *placeString = [NSString stringWithFormat:#"Text here."];
CGSize size = [placeString sizeWithAttributes:stringAttributes];
//Create a bitmap context into which the text will be rendered.
UIGraphicsBeginImageContext(size);
//Render the text.
[placeString drawAtPoint:CGPointMake(0.0, 0.0) withAttributes:stringAttributes];
//Retrieve the image.
UIImage *imagene = UIGraphicsGetImageFromCurrentImageContext();
UIImage *mergedImage = _imageView.image;
CGSize newSize = image.size;
UIGraphicsBeginImageContext(newSize);
//Use existing opacity as is.
[mergedImage drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
//Apply supplied opacity if applicable.
CGRect drawingRect = (CGRect) {.size = size};
drawingRect.origin.x = (newSize.width - size.width) * 0.01;
drawingRect.origin.y = (newSize.height - size.height) * 0.03;
[imagene drawInRect:drawingRect blendMode:kCGBlendModeNormal alpha:1];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[_imageView setImage:newImage];
self.imageView.image = newImage;
Here's a general approach, code is likely missing but it gives you the important bits.
CGContextRef ctx = CGBitmapContextCreate(...)
CGContextDrawImage (gtx, myContextRect, myimage);
CGContextSelectFont(ctx, "Helvetica", 10.0, kCGEncodingMacRoman);
CGContextSetCharacterSpacing(ctx, 1.7);
CGContextSetTextDrawingMode(ctx, kCGTextFill);
CGContextShowTextAtPoint(ctx, 100.0, 100.0, "SOME TEXT", 9);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
This will give you an image you can put in a view, or share via UIActivityViewController. I'm sure you can work out the bits.
The approach is:
1) Create bitmap context.
2) Render image
3) Add text
4) Save context to image
Simply place a UILabel on top of a UIImageView in IB and position them as desired using constraints. Then set the text into the label as desired.
EDIT:
Now that I know you want to be able to save I'd suggest using UIGraphicsBeginImageContextWithOptions to create an off-screen graphics context. I find that easier to deal with than CGContext and Core Graphics calls.
Draw into the context and the fetch and image from it.
Make the context the size of your image, and pass in a scale of 0 to use the device's native scale.
Your code might look something like this:
//Create an off-screen graphics context for drawing.
CGSize imageSize = myImage.size;
UIGraphicsBeginImageContextWithOptions(imageSize, false, 0);
//draw your image using drawAtPoint(CGPointmake(0,0));
//draw your string using one of the drawAtPoint or drawInRect methods
//available in NSString UIKit additions
//Fetch the resulting image from the context.
UIImage *maskImage = UIGraphicsGetImageFromCurrentImageContext();
//End the off-screen context
UIGraphicsEndImageContext();
Related
hi all i have looked at answers to similar questions and none seem to work for me. I am trying to water mark an image from the camera (image in the below) and add an image and text as a water mark. The below is working perfectly for adding the image but have no idea how to do the text.
WmarkImage = [UIImage imageNamed:#"60.png"];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
[WmarkImage drawInRect:CGRectMake(image.size.width - WmarkImage.size.width, image.size.height - WmarkImage.size.height, WmarkImage.size.width, WmarkImage.size.height)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[imageView setImage:image];
You should convert your text to image then merge them here is an code for this please check this.
NSString* kevin = #"Hello";
UIFont* font = [UIFont systemFontOfSize:12.0f];
CGSize size = [kevin sizeWithFont:font];
// Create a bitmap context into which the text will be rendered.
UIGraphicsBeginImageContext(size);
// Render the text
[kevin drawAtPoint:CGPointMake(0.0, 0.0) withFont:font];
// Retrieve the image
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIImage *MergedImage = [UIImage imageNamed:#"mark.png"];
CGSize newSize = CGSizeMake(200, 400);
UIGraphicsBeginImageContext( newSize );
// Use existing opacity as is
[MergedImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Apply supplied opacity if applicable
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.8];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(20, 20, 300, 400)];
[imageView setImage:newImage];
[self.view addSubview:imageView];
This might help..
CATextLayer *theTextLayer = [CATextLayer layer];
theTextLayer.string = #"Your Text here";
theTextLayer.font = #"Helvetica";
theTextLayer.fontSize = #"12"
theTextLayer.alignmentMode = kCAAlignmentCenter;
theTextLayer.bounds = CGRectMake(0, 0, 40, 40);//give whatever width or height you want
[imageview.layer addSubLayer:theTextLayer];
I am working on the picture caption app. For normal png picture all is working fine but my client ask me to create animated gif from the images. i have created animated gif using imageview animation property but the problem comes when i have to add caption on gif image and share that gif image with caption on it.I am sharing simple gif image by convering them into NSdata. Please advice me the right way to add caption on animated gif.
I have used below code to create gif image
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:path]),kUTTypeGIF,[camImages count],NULL);
NSDictionary *frameProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject: [NSNumber numberWithInt:2] forKey:(NSString *)#"0.15f"]
forKey:(NSString *)kCGImagePropertyGIFDictionary];
NSDictionary *gifProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount]
forKey:(NSString *)kCGImagePropertyGIFDictionary];
_image=[[UIImage alloc] init];
for(int i=0;i<camImages.count;i++)
{
_image =[camImages objectAtIndex:i];
CGImageDestinationAddImage(destination, _image.CGImage, (CFDictionaryRef)CFBridgingRetain(frameProperties));
}
CGImageDestinationSetProperties(destination, (CFDictionaryRef)CFBridgingRetain(gifProperties));
CGImageDestinationFinalize(destination);
You have every frame of the gif, so you can draw the title on every image of the gif on the same position, then you get new images and you will compose them into a new gif.
How to write text on image
It's a rotate text demo.
NSString * str = #"hello" ;
UIImage * image = [UIImage imageNamed:#"path"] ;
CGSize imageSize = image.size ;
UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0.0) ;
[image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)] ;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextRotateCTM(context, M_PI);
[[UIColor whiteColor] set] ;
[str drawInRect:CGRectMake(-imageSize.width, -imageSize.height, imageSize.width, imageSize.height) withFont:[UIFont systemFontOfSize:16.0]] ;
CGContextRestoreGState(context);
UIImage * compressedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
I'm trying to create a UIImage from an NSAttributedString that's has a skewed transform. I can make a UILabel or UIImageView and skew that view, but unfortunately I need to create a UIImage after the string has been skewed. I've tried the following..
CGAffineTransform skewTransform = CGAffineTransformIdentity;
skewTransform.b = (M_1_PI / 2);
UIGraphicsBeginImageContextWithOptions(mSize, NO, 1.0);
UILabel* skewedLabel = [[UILabel alloc] init];
skewedLabel.attributedText = stringToBeSkewed;
CGContextSetTextMatrix(UIGraphicsGetCurrentContext(), skewTransform);
skewedLabel.layer.affineTransform = skewTransform;
// The following 3 calls haven't worked
// [stringToBeSkewed drawInRect:inputRectParam.rect];
// [skewedLabel.layer renderInContext:UIGraphicsGetCurrentContext()];
// [skewedLabel.layer drawInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
I get that the CALayer is CoreAnimation and CoreGraphics doesn't recognize this, but is there a way to get skewed text to be captured within the context and converted into a UIImage?
I was able to get a UIImage from text by doing the following, hope this helps someone out. Also, it's not the cleanest image, so any advice on sharpening it up would be appreciated.
UIFont* font = [UIFont fontWithName:#"(your font name)" size:60];
CTFontRef skewFont = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize, NULL);
// Create an attributed string for shadowed text
CFStringRef skewKeys[] = { kCTFontAttributeName, kCTForegroundColorAttributeName };
CFTypeRef skewValues[] = { skewFont, [UIColor colorWithRed:0 green:0 blue:0 alpha:.4].CGColor };
CFDictionaryRef skewAttributes = CFDictionaryCreate(NULL, (const void **)&skewKeys, (const void **)&skewValues,
sizeof(skewKeys) / sizeof(skewKeys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFStringRef theCFString = (__bridge CFStringRef)inputStringParam.string;
CFAttributedStringRef skewString = CFAttributedStringCreate(NULL, theCFString, skewAttributes);
CFRelease(skewAttributes);
// create skew transform
CGAffineTransform skewTransform = CGAffineTransformIdentity;
skewTransform.b = (value to be skewed);
// Draw the string
CTLineRef skewLine = CTLineCreateWithAttributedString(skewString);
CGContextSetTextMatrix(UIGraphicsGetCurrentContext(), CGAffineTransformMakeScale(1.0, -1.0));
CGContextConcatCTM(UIGraphicsGetCurrentContext(), skewTransform);
// draw and capture shadow image
CGContextSetTextPosition(UIGraphicsGetCurrentContext(), inputDrawPointParam.point.x, inputDrawPointParam.point.y);
CTLineDraw(skewLine, UIGraphicsGetCurrentContext());
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CFRelease(skewLine);
CFRelease(skewString);
CFRelease(skewFont);
So the app I'm working on lets users write text, and the app translate that text into separate UILabels (one UILabel that only contains the text, and another UILabel that is the same width as the text, but with a transparent color background). I want to combine all the uilabels with the UIImage in the background to create a new UIImage.
So far I have the following code, but it does not produce any tangible results and would love anyone's help with this problem:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(320, 416), NO, 0.0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[_imgViewFinal.layer renderInContext:ctx];
CGContextSaveGState(ctx);
for (int i = 0; i < _allLabels.count; i++) {
UILabel *tempLabelBg = [_allBgs objectAtIndex:i];
CGContextTranslateCTM(ctx, tempLabelBg.frame.origin.x, tempLabelBg.frame.origin.y);
CGContextSaveGState(ctx);
[tempLabelBg.layer renderInContext:ctx];
CGContextRestoreGState(ctx);
UILabel *tempLabelText = [_allLabels objectAtIndex:i];
[tempLabelText drawTextInRect:tempLabelText.frame];
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
NSData *imgData = UIImageJPEGRepresentation(image, 1.0);
UIImage * imagePNG = [UIImage imageWithData:imgData];
UIGraphicsEndImageContext();
*I know that drawTextInRect does not use the contextref I create. I'm not sure how to draw the text into the context. I don't think I'm using the CGContextSave and Restore properly either.
UIGraphicsBeginImageContextWithOptions(myView.bounds.size, myView.opaque, 0.0);
[myView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
where myView is the view holding whatever you want in the image (img) we're creating.. I didn't test it for Labels, but it should work fine.
I've been researching this question but the answer I found does not work.
[myImageView addSubview:myTextView];
I want the text to become part of the image, so if I saved myImageView to the camera roll, the text would be included.
Am I doing something wrong or is there another way to do this?
Suppose you've already got a UIImage img, then use the following code to add texts
-(void)drawText:(NSString *)text onImage:(UIImage *)img
{
UIFont *font = yourTextViewFont;
UIGraphicsBeginImageContext(img.size);
[img drawAtPoint:CGPointZero];
CGContextSetRGBFillColor(UIGraphicsGetCurrentContext(), 1.0, 1.0, 1.0, 1);
[text drawAtPoint: CGPointMake(20, 20) withFont: font];
UIImage *ret = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return ret;
}