Image is getting stretched and blur after crop - iphone

I am having and UIImageView and there is another canvas view over the UIImageView. I want to cut the UIImageView's image according to the canvas view's frame. But after crop the image is getting stretched and blur after crop. Below are my codes.
[UIImage *images = [self captureScreenInRect1:canvas.frame];
self.imgViewCurrent.contentMode = UIViewContentModeScaleToFill;
self.imgViewCurrent.image = images;
- (UIImage *)captureScreenInRect1:(CGRect)captureFrame {
CALayer *layer;
layer = self.view.layer;enter image description here
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 1.0);
CGContextClipToRect (UIGraphicsGetCurrentContext(),captureFrame);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef imageRef = CGImageCreateWithImageInRect([screenImage CGImage], captureFrame);
UIImage *img = [UIImage imageWithCGImage:imageRef scale:0.0 orientation:UIImageOrientationUp];
CGImageRelease(imageRef);
return img;
}

change this line
self.imgViewCurrent.contentMode = UIViewContentModeScaleToFill;
to this line
self.imgViewCurrent.contentMode = UIViewContentModeScaleAspectFit
UIViewContentModeScaleToFill will basically stretches the image.

After cropping your image, you can resize your image with Custom Size. It may help you.
-(UIImage*) resizedImage:(UIImage *)inImage: (CGRect) thumbRect
{
CGImageRef imageRef = [inImage CGImage];
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
// There's a wierdness with kCGImageAlphaNone and CGBitmapContextCreate
// see Supported Pixel Formats in the Quartz 2D Programming Guide
// Creating a Bitmap Graphics Context section
// only RGB 8 bit images with alpha of kCGImageAlphaNoneSkipFirst, kCGImageAlphaNoneSkipLast, kCGImageAlphaPremultipliedFirst,
// and kCGImageAlphaPremultipliedLast, with a few other oddball image kinds are supported
// The images on input here are likely to be png or jpeg files
if (alphaInfo == kCGImageAlphaNone)
alphaInfo = kCGImageAlphaNoneSkipLast;
// Build a bitmap context that's the size of the thumbRect
CGContextRef bitmap = CGBitmapContextCreate(
NULL,
thumbRect.size.width, // width
thumbRect.size.height, // height
CGImageGetBitsPerComponent(imageRef), // really needs to always be 8
4 * thumbRect.size.width, // rowbytes
CGImageGetColorSpace(imageRef),
alphaInfo
);
// Draw into the context, this scales the image
CGContextDrawImage(bitmap, thumbRect, imageRef);
// Get an image from the context and a UIImage
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage* result = [UIImage imageWithCGImage:ref];
CGContextRelease(bitmap); // ok if NULL
CGImageRelease(ref);
return result;
}

Related

How to know if a UIImage is representable in PNG or JPG?

I got a UIImage from UIImagePickerController, and using the code from this site to resize the image
- (UIImage *)resizedImage:(CGSize)newSize
transform:(CGAffineTransform)transform
drawTransposed:(BOOL)transpose
interpolationQuality:(CGInterpolationQuality)quality {
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGRect transposedRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width);
CGImageRef imageRef = self.CGImage;
// Build a context that's the same dimensions as the new size
CGContextRef bitmap = CGBitmapContextCreate(NULL,
newRect.size.width,
newRect.size.height,
CGImageGetBitsPerComponent(imageRef),
0,
CGImageGetColorSpace(imageRef),
CGImageGetBitmapInfo(imageRef));
// Rotate and/or flip the image if required by its orientation
CGContextConcatCTM(bitmap, transform);
// Set the quality level to use when rescaling
CGContextSetInterpolationQuality(bitmap, quality);
// Draw into the context; this scales the image
CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef);
// Get the resized image from the context and a UIImage
CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
// Clean up
CGContextRelease(bitmap);
CGImageRelease(newImageRef);
return newImage;
}
UIImagePNGRepresentation() failed to return NSData on re-sized image, but UIImageJPEGRepresentation() succeed.
How do we know if a UIImage is presentable in PNG or JPEG? What missed in the above code that make the resized image can not be represented in PNG?
According to apple document: "This function may return nil if the image has no data or if the underlying CGImageRef contains data in an unsupported bitmap format."
What bitmap format supported by PNG presentation? How to make an UIImage PNG-supported format?
That was a mistake that in another part of the code the image was rescaled with the following
CGContextRef context = CGBitmapContextCreate(NULL,
size.width,
size.height,
8,
0,
CGImageGetColorSpace(source),
kCGImageAlphaNoneSkipFirst);
Changing kCGImageAlphaNoneSkipFirst to CGImageGetBitmapInfo(source) fixed the problem
go to following link...
How to check if downloaded PNG image is corrupt?
it may help you...
Let me know it is working or not...
Happy Coding!!!!

Display an Image that has to be resized in a UITableViewCell

Hi so i currently have a small image (about 100x160) as a NSData Attribute in my CoreData model.
i display all entities in a TableView. The UIImageView in a single Cell has only a size of 50x80. just dropping the image into this frame looks a bit pebbly.
what would be the best solution to display this image in my tableViewCell? resize it on-the-fly in my cellForRowAtIndexPath? probably this will lead up my tableview to become a bit laggy.
resize it on create and save it in my coredata entity (or probably on disk)?
thank you! please leave a comment if something is unclear
For that you have to crop/resize the image. Following is the code to crop the image as per the required frame.
- (void)viewDidLoad
{
[super viewDidLoad];
// do something......
UIImage *img = [UIImage imageWithData:(nsdata)]; // nsdata will be your image data as you specified.
// To crop Image
UIImage *croppedImage = [self imageByCropping:img] toRect:CGRectMake(10, 10, 50, 80)];
// To resize image
UIImage *resizedImage = [self resizeImage:img width:50 height:80];
}
Crop Image:
- (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
return cropped;
}
Resize Image:
-(UIImage *)resizeImage:(UIImage *)image width:(int)width height:(int)height
{
CGImageRef imageRef = [image CGImage];
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
alphaInfo = kCGImageAlphaNoneSkipLast;
CGContextRef bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), 4 * width, CGImageGetColorSpace(imageRef), alphaInfo);
CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage *result = [UIImage imageWithCGImage:ref];
return result;
}
You can go with either of ways.

stretch a image to a larger size without disturbing the pixels in iPhone

I have a view which has 3 subviews and all of the three subviews have uimageviews in uiscrolviews. So the imageviews can be scrolled or zoomed. The images are pretty large.
Now the total size of the view is 480X320 but I want to capture screen in bigger sizes e.g 960X640. But when I try to do it the image is stretched with pixels getting disturbed.
Is there a way to stretch a image which is large in size but displayed in small framed?
Thanks
Pankaj
try this code it's working for me.
-(UIImage *)resizeImage:(UIImage *)image width:(int)width height:(int)height {
CGImageRef imageRef = [image CGImage];
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
//if (alphaInfo == kCGImageAlphaNone)
alphaInfo = kCGImageAlphaNoneSkipLast;
CGContextRef bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), 4 * width, CGImageGetColorSpace(imageRef), alphaInfo);
CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage *result = [UIImage imageWithCGImage:ref];
CGContextRelease(bitmap);
CGImageRelease(ref);
return result;
}

Problem when masking UIImage

I took a sample code from the following URL: how to mask an image in order to mask an image.
The code is working perfectly on the iPhone simulator but works incorrectly on iPhone 4 simulator (that's when high-res images are loaded...)
Here is my code and the mask function:
- (void)someMethod {
UIImage* image = [UIImage imageNamed:#"image.png"]; // image#2x.png is loaded for high-res device
UIImage* mask = [UIImage imageNamed:#"mask.png"]; // mask#2x.png is loaded for high-res device
UIImage* maskedImage = [self maskImage:image withMask:mask];
// ... Some code here displaying maskedImage
}
- (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
UIImage* maskedImage = nil;
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
maskedImage = [UIImage imageWithCGImage:masked];
return maskedImage;
}
On the iPhone 4 simulator the image#2x.png and mask#2x.png are loaded and then the resulted maskedImage is cropped.
Any idea what am I doing wrong?
Use this method instead of above
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//UIImage *maskImage = [UIImage imageNamed:#"mask.png"];
CGImageRef maskImageRef = [maskImage CGImage];
// create a bitmap graphics context the size of the image
CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
if (mainViewContentContext==NULL)
return NULL;
CGFloat ratio = 0;
ratio = maskImage.size.width/ image.size.width;
if(ratio * image.size.height < maskImage.size.height) {
ratio = maskImage.size.height/ image.size.height;
}
CGRect rect1 = {{0, 0}, {maskImage.size.width, maskImage.size.height}};
CGRect rect2 = {{-((image.size.width*ratio)-maskImage.size.width)/2 , -((image.size.height*ratio)-maskImage.size.height)/2}, {image.size.width*ratio, image.size.height*ratio}};
CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);
// Create CGImageRef of the main view bitmap content, and then
// release that bitmap context
CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);
UIImage *theImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
// return the image
return theImage;
}
My guess would be to not trust UIImage to deliver the highrez format to CGImageRefs etc. I think you will need to do it manually.

iPhone BitmapImageRep

I have a buffer which has JPEG image data. I need to display this image in UIImageView. I need to convert this image buffer into an object of UIImage and use it as follows
NSData *data = [NSData dataWithContentsOfFile:appFile];
UIImage *theImage = [[UIImage alloc] initWithData:data];
I get the image displayed but with a low resolution as compared to the actual resolution. Do I need to convert it into a Bitmap first and then use it with UIImage? I don't seem to be able to use NSBitmapImageRep. Any ideas on how can this be achieved?
If the UIImageView frame dimensions are different than the source image dimensions, you'll get a resized version of the image. The quality can be pretty rough depending on how much of a conversion is being performed.
I found this code on the net somewhere (sorry original author - I've lost the attribution) that performs a smoother resize:
UIImage* resizedImage(UIImage *inImage, CGRect thumbRect)
{
CGImageRef imageRef = [inImage CGImage];
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
// There's a wierdness with kCGImageAlphaNone and CGBitmapContextCreate
// see Supported Pixel Formats in the Quartz 2D Programming Guide
// Creating a Bitmap Graphics Context section
// only RGB 8 bit images with alpha of kCGImageAlphaNoneSkipFirst, kCGImageAlphaNoneSkipLast, kCGImageAlphaPremultipliedFirst,
// and kCGImageAlphaPremultipliedLast, with a few other oddball image kinds are supported
// The images on input here are likely to be png or jpeg files
if (alphaInfo == kCGImageAlphaNone)
alphaInfo = kCGImageAlphaNoneSkipLast;
// Build a bitmap context that's the size of the thumbRect
CGContextRef bitmap = CGBitmapContextCreate(
NULL,
thumbRect.size.width, // width
thumbRect.size.height, // height
CGImageGetBitsPerComponent(imageRef), // really needs to always be 8
4 * thumbRect.size.width, // rowbytes
CGImageGetColorSpace(imageRef),
alphaInfo
);
// Draw into the context, this scales the image
CGContextDrawImage(bitmap, thumbRect, imageRef);
// Get an image from the context and a UIImage
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage* result = [UIImage imageWithCGImage:ref];
CGContextRelease(bitmap); // ok if NULL
CGImageRelease(ref);
return result;
}