I've been trying to use a method commonly used to resize an image. Without using this method, here is the code that takes a url of an image.
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
cell.imageView.image = img;
This works fine. But when I try to use this method:
-(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
and call it using this:
UIImage *scaledImage = [self imageWithImage:img scaledToSize:CGSizeMake(10.0f,10.0f)];
then putting into my table like this:
cell.imageView.image = scaledImage;
Nothing shows up. Is there something I'm missing here?
This is similar to Exporting customized UITableViewCells into UIImage
Here's what you need to do in your -imageWithImage:scaledToSize: method, modified from my answer to that question:
-(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize
{
// Create a bitmap context.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContextForScaledImage = CGBitmapContextCreate(nil, newSize.width, newSize.height, 8, 0, colorSpace, kCGImageAlphaNone);
CGColorSpaceRelease(colorSpace);
// Draw the image's layer into the context.
UIImageView * imageView = [[UIImageView alloc] initWithImage:image];
[imageView.layer renderInContext:bitmapContextForCell];
[imageView release];
// Create a CGImage from the context.
CGImageRef cgScaledImage = CGBitmapContextCreateImage(bitmapContextForScaledImage);
// Create a UIImage from the CGImage.
UIImage * scaledImage = [UIImage imageWithCGImage:cgScaledImage];
// Clean up.
CGImageRelease(cgScaledImage);
CGContextRelease(bitmapContextForScaledImage);
return scaledImage;
}
Related
I want to crop UIImage with the following code:
- (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
// or use the UIImage wherever you like
UIImage * img = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return img;
}
This code is working fine in the simulator but giving unusual result on device.
Create a UIImage category and try adding this.
#implementation UIImage (Crop)
- (UIImage *)crop:(CGRect)cropRect {
cropRect = CGRectMake(cropRect.origin.x*self.scale,
cropRect.origin.y*self.scale,
cropRect.size.width*self.scale,
cropRect.size.height*self.scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], cropRect);
UIImage *result = [UIImage imageWithCGImage:imageRef
scale:self.scale
orientation:self.imageOrientation];
CGImageRelease(imageRef);
return result;
}
Try this one :
- (UIImage *)cropImage:(UIImage *)oldImage {
CGSize imageSize = oldImage.size;
UIGraphicsBeginImageContextWithOptions(CGSizeMake( imageSize.width,imageSize.height - 150),NO,0.);
[oldImage drawAtPoint:CGPointMake( 0, -80) blendMode:kCGBlendModeCopy alpha:1.];
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return croppedImage;
}
I am trying to capture (screen shot) a view. For that I am using a piece of code shown below that saves it to my document directory as a PNG image.
UIGraphicsBeginImageContextWithOptions(highlightViewController.fhView.centerView.frame.size, YES, 1.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:#"1.png"];
NSData *imageData = UIImagePNGRepresentation(screenshot);
[imageData writeToFile:appFile atomically:YES];
UIGraphicsEndImageContext();
Question: can I capture part of the view? Because in the above code I can't change the origin (frame). If anyone has other approach to capture a particular part of view please share it.
You could crop the image:
http://iosdevelopertips.com/graphics/how-to-crop-an-image.html
CGRect rect = CGRectMake(0,0,10,10);
CGImageRef imageRef = CGImageCreateWithImageInRect([screenshot CGImage], rect);
UIImage *croppedScreenshot = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
Try this code. This surely works as I have implemented it in many of my projects:
- (UIImage *)image
{
if (cachedImage == nil) {
//YOU CAN CHANGE THE FRAME HERE TO WHATEVER YOU WANT TO CAPTURE
CGRect imageFrame = CGRectMake(0, 0, 400, 300);
UIView *imageView = [[UIView alloc] initWithFrame:imageFrame];
[imageView setOpaque:YES];
[imageView setUserInteractionEnabled:NO];
[self renderInView:imageView withTheme:nil];
UIGraphicsBeginImageContext(imageView.bounds.size);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextGetCTM(c);
CGContextScaleCTM(c, 1, -1);
CGContextTranslateCTM(c, 0, -imageView.bounds.size.height);
[imageView.layer renderInContext:c];
cachedImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
// rescale graph
UIImage* bigImage = UIGraphicsGetImageFromCurrentImageContext();
CGImageRef scaledImage = [self newCGImageFromImage:[bigImage CGImage] scaledToSize:CGSizeMake(100.0f, 75.0f)];
cachedImage = [[UIImage imageWithCGImage:scaledImage] retain];
CGImageRelease(scaledImage);
UIGraphicsEndImageContext();
[imageView release];
}
return cachedImage;
}
I hope this will help you.
See if you can specify the rect like this and then take screenshot.
CGRect requiredRect = CGRectMake(urView.frame.origin.x, urView.frame.origin.y, urView.bounds.size.width, urView.bounds.size.height);
UIGraphicsBeginImageContext(requiredRect.size);
You can alter the origin and see if it works.
If this doesn't work out, you can try cropping the image as mentioned by #mcb
You can use this code
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect rect;
rect = CGRectMake(250,61 ,410, 255);
CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
CGImageRelease(imageRef);
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.
I'm trying to create a UIPickerView with some images in it, but I can't seem to figure out how to get the images to fit in the view (right now they're too large and are overlapping each other).
I'm trying to use a function to resize each image when it's drawn, but I'm getting errors when the function is called, although the program compiles and runs fine (with the exception of the image not resizing). The resizing function and initialization functions are:
-(UIImage *)resizeImage:(UIImage *)image width:(int)width height:(int)height {
NSLog(#"resizing");
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;
}
- (void)viewDidLoad {
UIImage *h1 = [UIImage imageNamed:#"h1.png"];
h1 = [self resizeImage:h1 width:50 height: 50];
UIImageView *h1View = [[UIImageView alloc] initWithImage:h1];
NSArray *imageViewArray = [[NSArray alloc] initWithObjects:
h1View, nil];
NSString *fieldName = [[NSString alloc] initWithFormat:#"column1"];
[self setValue:imageViewArray forKey:fieldName];
[fieldName release];
[imageViewArray release];
[h1View release];
}
Console Output:
TabTemplate[29322:207] resizing
TabTemplate[29322] : CGBitmapContextCreate: unsupported colorspace
TabTemplate[29322] : CGContextDrawImage: invalid context
TabTemplate[29322] : CGBitmapContextCreateImage: invalid context
I can't figure out what's going wrong. Any help is greatly appreciated.
You don't require to resize your UIImage if you use the contentMode property of UIImageView.
myImageView.contentMode = UIViewContentModeScaleAspectFit;
Or if you still want to resize your UIImage, Have look at below SO post.
resizing a UIImage without loading it entirely into memory?
UIImage: Resize, then Crop
Use below to scale the image using aspect ratio, then clip the image to imageview's bounds.
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
In case of swift
imageView.contentMode = .ScaleAspectFill
imageView.clipsToBounds = true
UIImage *image = [UIImage imageNamed:#"myImage"];
[image drawInRect: destinationRect];
UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIImageWriteToSavedPhotosAlbum(image,nil,nil,nil);
Here's the code I have but it's crashing ... any ideas?
UIImage *tempImage = [[UIImage alloc] initWithData:imageData];
CGImageRef imgRef = [tempImage CGImage];
[tempImage release];
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGRect bounds = CGRectMake(0, 0, width, height);
CGSize size = bounds.size;
CGAffineTransform transform = CGAffineTransformMakeScale(4.0, 4.0);
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextConcatCTM(context, transform);
CGContextDrawImage(context, bounds, imgRef);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
What am I missing here? Basically just trying to scale image up and crop it to be same size as original.
Thanks
The problem is this line:
CGImageRef imgRef = [tempImage CGImage];
Or more precise, the direct follow-up of this line:
[tempImage release];
You are getting a CF object here, the CGImageRef. Core Foundation object only have the retain/release memory management, but no autoreleased objects. Hence, when you release the UIImage in the second row, the CGImageRef will be deleted as well. And this again means that it's undefined when you try to draw it down there.
I can think of three fixes:
use autorelease to delay the release of the image: [tempImage autorelease];
move the release to the very bottom of your method
retain and release the image using CFRetain and CFRelease.
Try this one:
-(CGImageRef)imageCapture
{
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect rect= CGRectMake(0,0 ,320, 480);
CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], rect);
return imageRef;
}
use the below line whenever you want to capture the screen
UIImage *captureImg=[[UIImage alloc] initWithCGImage:[self imageCapture]];