UIImageJPEGRepresentation giving 2x images on retina display - iphone

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.

Related

Why do I lost UIImage quality when I want to color it

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 ?

capture screen as it looks like

iam doing one application.In that Im using one imageview with image and add one view with sone clear holes.Means through that holes we can see the background image.So my problem is i want to capture that total screen (imageview with this holes view).Iam using below code but it's not working.
- (UIImage*)captureView:(UIView *)yourView {
CGRect rect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[yourView.layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
but it's not working.
This IS how we do:
UIGraphicsBeginImageContextWithOptions(yourView.bounds.size, yourView.opaque, 0.0);
[yourView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *LastImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Try this to take your screeShoT
-(UIImage*)getScreenShot
{
CGSize screenSize = [[UIScreen mainScreen] applicationFrame].size;
//CGSize screenSize = CGSizeMake(1024, 768);
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(nil, screenSize.width, 416, 8, 4*(int)screenSize.width, colorSpaceRef, kCGImageAlphaPremultipliedLast);
CGContextTranslateCTM(ctx, 0.0, screenSize.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
[(CALayer*)self.yourView.layer renderInContext:ctx];
CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
UIImage *image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
CGContextRelease(ctx);
return image;
}

Splitting an UIImage in two different UIimageviews in CoreGraphics-iPhone

Problem: I have an three UIImageViews. One has an UIImage and the other two are namely - leftImageView & rightImageView. The leftImageView has the left half of the image and the right one has the other. I am trying to achieve this using Coregraphics, i.e. drawing an image in the two imageviews.
But the right imageview isn't showing up. Refer to the code below:
UIImage *image = imgView.image;
CGSize sz = [image size];
CGRect leftRect = CGRectMake(0, 0, imgView.frame.size.width/2, imgView.frame.size.height);
CGRect rightRect = CGRectMake(imgView.frame.size.width/2, 0, imgView.frame.size.width/2, imgView.frame.size.height);
CGImageRef leftReference = CGImageCreateWithImageInRect([image CGImage], leftRect);
CGImageRef rightReference = CGImageCreateWithImageInRect([image CGImage], rightRect);
// Left Image ...
UIGraphicsBeginImageContextWithOptions(CGSizeMake(leftRect.size.width, leftRect.size.height), NO, 0);
CGContextRef con = UIGraphicsGetCurrentContext();
CGContextDrawImage(con, leftRect,flip(leftReference));
imgViewLeft = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
[self.view addSubview:imgViewLeft];
// Right Image ...
UIGraphicsBeginImageContextWithOptions(CGSizeMake(rightRect.size.width, rightRect.size.height), NO, 0);
con = UIGraphicsGetCurrentContext();
CGContextDrawImage(con, rightRect,flip(rightReference));
imgViewRight = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
[self.view addSubview:imgViewRight];
I think that you can use the following code part.
UIImage *image = [UIImage imageNamed:#"xxx.png"]; // You can change this line.
BOOL isLeft = YES; // You can change this variable(isLeft = YES : left piece, NO : right piece).
UIGraphicsBeginImageContext(CGSizeMake(image.size.width / 2, image.size.height));
CGContextRef context = UIGraphicsGetCurrentContext();
if (isLeft)
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
else
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(- image.size.width / 2, 0, image.size.width, image.size.height), image.CGImage);
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageCopy;
I couldn't launch this code now, but I think that my code is almost correct. Please try this.
Edit :
In your code :
// Right Image ...
UIGraphicsBeginImageContextWithOptions(CGSizeMake(rightRect.size.width, rightRect.size.height), NO, 0);
con = UIGraphicsGetCurrentContext();
CGContextDrawImage(con, rightRect,flip(rightReference));
imgViewRight = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
There is a wrong part in the third line :
CGContextDrawImage(con, rightRect,flip(rightReference));
It should be
CGContextDrawImage(con, leftRect,flip(rightReference));

How to combine UIImage and UILabel into one image and save

I have 2 UILabels and 2 images that i need to merge into a single UIImage to save.
I know I could do it with screen shots but my main image is rounded so if I rect it, it will still show the sharp edge.
I can do this to combine the images :
//CGSize newImageSize = CGSizeMake(cropImage.frame.size.width, cropImage.frame.size.height);
CGSize newImageSize = CGSizeMake(480, 320);
NSLog(#"CGSize %#",NSStringFromCGSize(newImageSize));
UIGraphicsBeginImageContextWithOptions(newImageSize, NO, 0.0); //retina res
[self.viewForImg.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
NSData *imgData = UIImageJPEGRepresentation(image, 0.9); //UIImagePNGRepresentation ( image ); // get JPEG representation
UIImage * imagePNG = [UIImage imageWithData:imgData]; // wrap UIImage around PNG representation
UIGraphicsEndImageContext();
return imagePNG;
but not sure how to add in the UILabel.
Any reply is much appreciated.
Use [myLabel.layer renderInContext:UIGraphicsGetCurrentContext()]; to draw in current context.
For eg:-
UIGraphicsBeginImageContextWithOptions(newImageSize, NO, 0.0); //retina res
[self.viewForImg.layer renderInContext:UIGraphicsGetCurrentContext()];
[myLabel.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
Based on your comments, if you want to draw this in a particular frame do it as follows,
[myLabel drawTextInRect:CGRectMake(0.0f, 0.0f, 100.0f, 50.0f)];
If you want to color the background, try this,
CGRect drawRect = CGRectMake(rect.origin.x, rect.origin.y,rect.size.width, rect.size.height);
CGContextSetRGBFillColor(context, 100.0f/255.0f, 100.0f/255.0f, 100.0f/255.0f, 1.0f);
CGContextFillRect(context, drawRect);
or you can check this question Setting A CGContext Transparent Background.
UIEdgeInsets insets = UIEdgeInsetsMake(1, 1, 1, 1);
CGSize imageSizeWithBorder = CGSizeMake(view.frame.size.width + insets.left + insets.right, view.frame.size.height + insets.top + insets.bottom);
UIGraphicsBeginImageContextWithOptions(imageSizeWithBorder, UIEdgeInsetsEqualToEdgeInsets(insets, UIEdgeInsetsZero), 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClipToRect(context, (CGRect){{insets.left, insets.top}, view.frame.size});
CGContextTranslateCTM(context, -view.frame.origin.x + insets.left, -view.frame.origin.y + insets.top);
[view.layer renderInContext:context];
UIImage *viewCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Try this!
UIGraphicsBeginImageContextWithOptions(newImageSize, NO, scale); //retina res
[COGI.layer renderInContext:UIGraphicsGetCurrentContext()];
[COGI.image drawInRect:CGRectMake(0, 0, 248, 290)];
[iconI.image drawInRect:CGRectMake(4, 20, 240, 240)];
[stampI.image drawInRect:CGRectMake(0, -5, 248, 290)];
[headerL drawTextInRect:CGRectMake(14, 35, 220, 40)];
[detailL drawTextInRect:CGRectMake(16, 200, 215, 65)];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
[[UIColor redColor] set];
NSData *imgData = UIImageJPEGRepresentation(image, 1.0); //UIImagePNGRepresentation ( image ); // get JPEG representation
UIImage * imagePNG = [UIImage imageWithData:imgData]; // wrap UIImage around PNG representation
UIGraphicsEndImageContext();
return imagePNG;

Rotated images having jagged borders even after adding transparent border

In my app I need to rotate images.I rotated the images but they have jagged borders.I googled and found that adding transparent border solves the problem, but the borders are still jagged.
My code is
-(void)CreateRotatedImage:(UIImage *)image Number:(int)Number
{
UIImage *ImageBackground=[UIImage imageNamed:#"white-highlight.png"];
CGSize ImageBackgroundSize = CGSizeMake(60, 50);
UIGraphicsBeginImageContext(ImageBackgroundSize);
CGRect ImageBackgroundRect = CGRectMake(0.0, 0.0, ImageBackgroundSize.width, ImageBackgroundSize.height);
[ImageBackground drawInRect:ImageBackgroundRect];
ImageBackground = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGSize ImageSize = CGSizeMake(50, 40);
UIGraphicsBeginImageContext(ImageSize);
CGRect ImageRect = CGRectMake(0.0, 0.0, ImageSize.width, ImageSize.height);
[image drawInRect:ImageRect];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContext(CGSizeMake(60,50));
[ImageBackground drawAtPoint:CGPointMake(0,0)];
[image drawAtPoint:CGPointMake(5,5)];
// MyscrollView.backgroundColor = [UIColor clearColor];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *pin=[UIImage imageNamed:#"pin.png"];
UIGraphicsBeginImageContext(CGSizeMake(60,50));
[newImage drawAtPoint:CGPointMake(0,0)];
[pin drawAtPoint:CGPointMake(newImage.size.height/2,0)];
// MyscrollView.backgroundColor = [UIColor clearColor];
UIImage *IntermediateImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect imageRrect = CGRectMake(0, 0, IntermediateImage.size.width, IntermediateImage.size.height);
UIGraphicsBeginImageContext( imageRrect.size );
[IntermediateImage drawInRect:CGRectMake(2,2,IntermediateImage.size.width-2,IntermediateImage.size.height-2)];
UIImage *i = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGSize iSize = CGSizeMake(110, 70);
UIGraphicsBeginImageContext(iSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetAllowsAntialiasing(context, YES);
CGContextSetShouldAntialias(context, YES);
CGContextRotateCTM (context, radians(5));
[i drawAtPoint:CGPointMake(0, 0)];
UIImage *RotatedImage=UIGraphicsGetImageFromCurrentImageContext();
//RotatedImage=[RotatedImage resizedImage:iSize interpolationQuality:kCGInterpolationHigh];
}