I'm learning about basic manipulation of UIImages using Objective-C on iOS. Say I have a square 128x128 image. How can I crop the bottom half of the image and store just the top half in a 128x64 image?
What you do is get a smaller CGImageRef from the UIImage's CGImage:
CGImageCreateWithImageInRect([image CGImage], someRect);
With that image you can then create a new image:
UIImage *nImage = [UIImage alloc] initWithCGImage:nImageRef];
Oops almost forgot, after you do the above:
CGImageRelease(nImageRef);
Related
I have collection view with some videos and images
Using AVFoundation able to capture video from iPhone and generated thumbnail using AVAssetImageGenerator. When shown in gallery image should distinguish it's of video thumbnail. So i need to transform exact image by drawing video symbol(like play icon) over it.
Is it possible?
You could use CoreGraphics to edit the image.
First, create a UIImage with the image you would like to edit. Then, do something like this:
UIImage *oldThumbnail; //set this to the original thumbnail image
UIGraphicsBeginImageContext(oldThumbnail.size);
[oldThumbnail drawInRect:CGRectMake(0, 0, oldThumbnail.size.width, oldThumbnail.size.height)];
/*Now there are two ways to draw the play symbol.
One would be to have a pre-rendered play symbol that you load into a UIImage and draw with drawInRect */
UIImage *playSymbol = [UIImage imageNamed:"PlaySymbol.png"];
CGRect playSymbolRect; //I'll let you figure out calculating where you should draw the play symbol
[playSymbol drawInRect: playSymbolRect];
//The other way would be to draw the play symbol directly using CoreGraphics calls. Start with this:
CGContextRef context = UIGraphicsGetCurrentContext();
//now use CoreGraphics calls. I won't go over it here, butthe second answer to this questionmay be helpful.
//Once you have finished drawing your image, you can put it in a UIImage.
UIImage *newThumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext(); //make sure you remember to do this :)
Now you can use the newly generated thumbnail in a UIImageView, cache it so you don't need to re-render it every time, etc.
This should work (you may have to play with positions and sizes):
-(UIImage*)drawPlayButton:(UIImage*)image
{
UIImage *playButton = [UIImage imageNamed:#"playbutton.png"];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
[playButton drawInRect:CGRectMake(image.size.width/2-playButton.size.width/2, image.size.height/2-playButton.size.height/2, playButton.size.width, playButton.size.height)];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
Through Face Detection, I want to blur eyes and mouth of a person. So I have a imageView that contains 3 subviews (2 per eye and the mouth). Each one of these subviews were masked with a PNG shape (with background clear) for avoiding to show rectangle.
My imageView in screen remain so: http://screencast.com/t/ak4SkNXM0I
And I want to obtain the image for storing in another place, so I've tried this:
CGSize size = [imageView bounds].size;
UIGraphicsBeginImageContext(size);
[[imageView layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
But finalImage is an image like this:
http://screencast.com/t/eDlvGqqY
My subViews (eyes and mouth) are not masked as above.
Any idea?
Thanks.
Edit:
I have to use library compatible with ios6
You can check the new API added to iOS7. Try one of the following methods:
snapshotViewAfterScreenUpdates:
resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets: for resizable image
drawViewHierarchyInRect:afterScreenUpdates:
How to draw beziercurve above the image of the UIImageView. I am subclassing UIImageView and drawing circles using UIBezierCurve on the corners of image view. But as soon as i place the image in UIImageView the inside part of circles are overlapped by the image. So is there any solution which lets me draw the UIBezier path on the UIimage of uiimageview ?
You can try subclassing simple UIView and drawing an image yourself using drawInRect: method of UIImage instance. It should look something like this:
- (void)drawRect:(CGRect)dirtyRect {
// note you can get image from anywhere
UIImage *image = [UIImage imageNamed:#"MyImage"];
[image drawInRect:self.bounds];
// now that image is drawn, everything
// past this point will be drawn on top of it
...
}
I have a png that I'm using as an image mask for another image. Both image have rounded corners that are being preserved with resizableImageWithCapInsets:. The image (not the mask) is being sized automatically because it is the progressImage of a UIProgressView.
The problem I'm having is that if I use CGImageMaskCreate to create a mask and simply give it the width of of the width of the UIProgressView, the mask image is being stretched (ie, it does not preserve the caps).
What I'd like to do is create a new UIImage with resizable caps, manually resize the image (perhaps by putting it in a UIImageView), get the data representation of the resized version of the mask image, then create a new image with that data and use that image as the mask. It seems, though, that even if I create a UIImageView with the image, and then set the frame of the UIImageView appropriately, getting the image back out of the view gives my original image.
Is there any way to get the result of a resizableImageWithCapInsets: image without it actually being drawn into the UI?
I would try drawing image piece by piece into CGContext where you can access data provider or extract NSData through creating UIImage
- (UIImage*) drawImage:(UIImage *)image
atSize:(CGSize) size
{
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
CGImageRef cgImage = CGBitmapContextCreateImage(context);
UIImage *outImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
UIGraphicsEndImageContext();
return outImage;
}
I am downloading images from a webserver for display in a table view in my iOS application using the following code:
NSURL *url = [NSURL URLWithString:[imageArray objectAtIndex:indexPath.row]];
UIImage *myImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
cell.imageView.image = myImage;
The image view is a 60x60 placeholder and 120x120 for the retina display. I am going to assume the user has an iPhone 4. However, if I size the image to 120x120 it does not correct the issue, it just becomes too big for the the imageview. If I size the image to 60x60, on the webserver that is, then the image fits fine but its a little fuzzy. Anyone know how to fix this issue?
Thanks!
Let's first agree that your UIImageView is 60x60 points, meaning 60x60 pixels for a standard display and 120x120 pixels for a retina display.
For a UIImageView at 60x60 points, the image should be 60x60 pixels at scale 1.0 for a standard display and 120x120 pixels at scale 2.0 for a retina display. This means that your UIImage should always have a size of 60x60 points, but should have a different scale depending on the display resolution.
When getting the image data from your server, you should first check the scale of the device's screen and then request the appropriate image size (in pixels), like so:
if ([UIScreen mainScreen].scale == 1.0) {
// Build URL for 60x60 pixels image
}
else {
// Build URL for 120x120 pixels image
}
Then you should put the image data in a UIImage of size 60x60 points, at the appropriate scale:
NSData *imageData = [NSData dataWithContentsOfURL:url];
CFDataRef cfdata = CFDataCreate(NULL, [imageData bytes], [imageData length]);
CGDataProviderRef imageDataProvider = CGDataProviderCreateWithCFData (cfdata);
CGImageRef imageRef = CGImageCreateWithJPEGDataProvider(imageDataProvider, NULL, true, kCGRenderingIntentDefault);
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef
scale:[UIScreen mainScreen].scale
orientation:UIImageOrientationUp];
CFRelease (imageRef);
CFRelease (imageDataProvider);
CFRelease(cfdata);
Hope this helps.
If your downloaded image have a size 2X from your UIImageView dimension size. It's look fine for retina display in iPhone4.
see also there: http://mobile.tutsplus.com/tutorials/iphone/preparing-your-iphone-app-for-higher-resolutions/
Images downloaded from the web are not formatted for Retina Display the same way images bundled with your app (using the "#2x" suffix) are.
You can get/set the scale of any UIView with the aptly named scale: and setScale: methods to help you better display content from the web if you know it's intended for Retina Display devices.
Well the answer is as simple as it can be:
I would recommend always downloading the double density images from the server (as users with non retina display are very few) and setting in the imageview.
What you didn't do correctly is you didn't set the imageView to automatically fit the content.
You can do this either in IB by selecting the ImageView and setting the contentMode (mode) to scale to Fill, or by code:
imageView.contentMode = UIViewContentModeScaleToFill;