I have this code, to draw some text inside a (so far) simple button:
UIImage *buttonImage(CGRect bounds, UIColor *fillColor, NSString *title) {
UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, fillColor.CGColor);
CGContextFillRect(context, bounds);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
[title drawInRect:bounds withFont:PanelButtonFont];
UIGraphicsEndImageContext();
return image;
}
The problematic part is the drawInRect. It's simply not drawing my text. The font is correct, and I've tested this with normal font code there, so it's not that. I think perhaps it doesn't realise that I want it to draw it onto the image that it's producing?
Just change the order and get the image after you draw the text:
UIImage *buttonImage(CGRect bounds, UIColor *fillColor, NSString *title) {
UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, fillColor.CGColor);
CGContextFillRect(context, bounds);
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
[title drawInRect:bounds withFont:PanelButtonFont];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Related
I'm currently using this code to color a white UIImage with a desired color. But after treatment, it appears that the image (embedded in a UIImageView with the good size of the original image) lost its quality.
+ (UIImage *)imageNamed:(NSString *)name withColor:(UIColor *)theColor
{
UIImage *baseImage = [UIImage imageNamed:name];
UIGraphicsBeginImageContext(baseImage.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect area = CGRectMake(0, 0, baseImage.size.width, baseImage.size.height);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -area.size.height);
CGContextSaveGState(ctx);
CGContextClipToMask(ctx, area, baseImage.CGImage);
[theColor set];
CGContextFillRect(ctx, area);
CGContextRestoreGState(ctx);
CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
CGContextDrawImage(ctx, area, baseImage.CGImage);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Any suggestion on how to fix this issue ?
I need to export UITableViewCell into an image PNG or anything so I can send it as a print screen image embedded in email body using the MFMailComposerViewController.
Use these methods. Just call UIImage *image = [cell screenshot];
- (UIImage *)screenshot
{
return [self screenshotForRect:self.bounds];
}
- (UIImage *)screenshotForRect:(CGRect) rect
{
UIGraphicsBeginImageContext(rect.size);
[[UIColor clearColor] setFill];
[[UIBezierPath bezierPathWithRect:rect] fill];
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.layer renderInContext:ctx];
UIImage *anImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return anImage;
}
- (UIImage *)captureCell {
//hide controls if needed
CGRect rect = [yourTableCell bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[yourTableCell.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
try something like that:
UIGraphicsBeginImageContext(yourTableViewCellView.bounds.size);
[yourTableViewCellView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
and then you can save the image to data :)
I have this code, which creates an image, and then adds some effects to it and sizes it down to make largeThumbnail.
UIImage *originalImage = [UIImage imageWithData:self.originalImage];
thumbnail = createLargeThumbnailFromImage(originalImage);
NSLog(#"thumbnail: %f", thumbnail.size.height);
NSData *thumbnailData = UIImageJPEGRepresentation(thumbnail, 1.0);
Later on:
UIImage *image = [UIImage imageWithData:self.largeThumbnail];
NSLog(#"thumbnail 2: %f", image.size.height);
NSLog returns:
thumbnail: 289.000000
thumbnail 2: 578.000000
As you can see, when it converts the image back from data, it makes it 2x the size. Any ideas why this may be happening?
Large thumbnail code:
UIImage *createLargeThumbnailFromImage(UIImage *image) {
UIImage *resizedImage;
resizedImage = [image imageScaledToFitSize:LARGE_THUMBNAIL_SIZE];
CGRect largeThumbnailRect = CGRectMake(0, 0, resizedImage.size.width, resizedImage.size.height);
UIGraphicsBeginImageContextWithOptions(resizedImage.size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
//Image
CGContextTranslateCTM(context, 0, resizedImage.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, largeThumbnailRect, resizedImage.CGImage);
//Border
CGContextSaveGState(context);
CGRect innerRect = rectForRectWithInset(largeThumbnailRect, 1.5);
CGMutablePathRef borderPath = createRoundedRectForRect(innerRect, 0);
CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);
CGContextSetLineWidth(context, 3);
CGContextAddPath(context, borderPath);
CGContextStrokePath(context);
CGContextRestoreGState(context);
UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return thumbnail;
}
Try replacing the part where you load the second image:
UIImage *image = [UIImage imageWithData:self.largeThumbnail];
with this one:
UIImage *jpegImage = [UIImage imageWithData:self.largeThumbnail];
UIImage *image = [UIImage imageWithCGImage:jpegImage.CGImage scale:originalImage.scale orientation:jpegImage.imageOrientation];
What happens here is that the image scale is not set, so you get double image dimensions.
I need to draw a rect filled with color and its border...
the rect is filled with color properly but the outside border is partially drawn, just the right side of the rect is drawn!
The generated UIImage is going to be used in a UITableViewCell's imageView.
- (UIImage *)legendItemWithColor:(UIColor *)color
{
UIGraphicsBeginImageContext(self.view.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect outside = CGRectMake(128, 128, 128, 128);
CGRect legend = CGRectInset(outside, 1, 1);
NSLog(#"Outside: %#", NSStringFromCGRect(outside));
NSLog(#"Legend: %#", NSStringFromCGRect(legend));
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, legend);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextStrokeRect(context, outside);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsPopContext();
return img;
}
The problem is when you pass self.view.frame.size to UIGraphicsBeginImageContext() and then use drawn rectangle in array, it is downscaled and the border is obfuscated. Try to pass only the size you need so, i.e. CGSizeMake(2*128+128+2,2*128+128+2). Then it displays ok
I am wanting to draw an NSString and a border onto a UIImage that I already have. I found a method that will draw an NSString as a UIImage, but I need it to draw on an image that I provide.
-(UIImage *)imageFromText:(NSString *)text
{
// set the font type and size
UIFont *font = [UIFont systemFontOfSize:20.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(1.0, 1.0), 5.0, [[UIColor grayColor] CGColor]);
// 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;
}
How would I modify this method to provide my own background image, as well as adding a border?
If you are displaying the UIImage in a UIImageView you can set the UIImageView.layer.delegate and use something like:
- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
CGContextSetFillColorWithColor(ctx, [[UIColor darkTextColor] CGColor]);
UIGraphicsPushContext(ctx);
[word drawAtPoint:CGPointMake(30.0f, 30.0f)
forWidth:200.0f
withFont:[UIFont boldSystemFontOfSize:32]
lineBreakMode:UILineBreakModeClip];
UIGraphicsPopContext();
}
Code from Add text to CALayer
The border is easy, just use the CALayer properties:
imageview.layer.borderColor = [UIColor blackColor].CGColor;
imageview.sublayer.borderWidth = 2.0;
You are looking for CALayers.
Here is very good tutorial how to create and use them.
So basically you will add new CALayer with image as a background and then draw on it text.
http://www.raywenderlich.com/2502/introduction-to-calayers-tutorial
Use this function to Draw NSString and border on UIImage
For border check CGContextSetRGBStrokeColor
-(UIImage *)imageFromText:(NSString *)text
{
// set the font type and size
UIFont *font = [UIFont systemFontOfSize:20.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(1.0, 1.0), 5.0, [[UIColor brownColor] CGColor]);
// draw in context, you can use also drawInRect:withFont:
[text drawAtPoint:CGPointMake(0.0, 0.0) withFont:font];
//CGImageRef cimg = UIGraphicsGetCurrentContext();
// transfer image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
[image drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];
//CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(ctx, 2.0, 3.5, 5.0, 1.0);
CGContextStrokeRect(ctx, rect);
UIImage *testImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return testImg;
}