Draw selected areas of a UIImage - iphone

I have a UIImage containing an image with a whole bunch of smaller pictures on the image (essentially an image strip containing sprites). I'd like to draw a single sprite onto an area of my UIView.
I can't seem to find a way draw only part of the UIImage onto the view. Is there a method that does this?

I think you may be looking for CGImageCreateWithImageInRect(). You can get a CGImage from a UIImage with the property of the same name.
EDIT: another option that exists in 2014, that did not in 2009, is SpriteKit. Depending on what you might be doing that needs a sprite sheet, that might be useful.

I wrote a UIImage category for handling sprite sheets. Check this out, it may be helpful http://reecon.wordpress.com/2011/11/19/uiimage-sprite-additions-objective-c/
As noted earlier, this category bases on CGImageCreateWithImageInRect() but makes the process of extracting sprites from a single sprite sheet far more convenient and faster.
Link to git hub page:
https://github.com/r3econ/UIImage-Sprite-Additions
You can also install using cocoa pods.

Yep, you sure can with Quartz.
There is a tutorial here that shows you how to take a UIImage and mask a part of it.
http://iosdevelopertips.com/cocoa/how-to-mask-an-image.html
Here is the code from that page (incase it goes down for some reason)
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
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);
return [UIImage imageWithCGImage:masked];
}

Related

How to draw a thought bubble in iOS

I am trying to create a thought bubble in iOS and want to fill it with image. I have gone through lots of results returned by internet search engines, but I did not get any solution.
The bubble, I want to create will be like the attached image below.
So you want to mask the image in the bubble.
So make the bubble internally full black.(To use for masking) and use the bellow function for masking.
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
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);
return [UIImage imageWithCGImage:masked];
}
for more sample tutorial visit the following links :-)
http://jeroendeleeuw.com/post/33638733049/how-to-mask-images-with-core-graphics-in-ios
http://iosdevelopertips.com/cocoa/how-to-mask-an-image.html
What I would do is create the inside of the bubble transparent, then create a UIImageView with it and add the image you want inside as a subview of it.
If you set clipToBounds property in the view to YES, the subview will stay inside the bubble!
use a UIView and add two imageViews into it, one will contain the bubble and the other the image you want.make the uiview background color clearColor

Rotating portrait UIImage that somehow has a UIImageOrientationRight orientation

Hi everyone,
I'm having an issue rotating a portrait UIImage (i.e. WIDTH < HEIGHT) that somehow has an orientation equal to UIImageOrientationRight. I'm not sure how this comes to be but it happens with a few images in my library captured with an iPhone 4.
This is my code (that does work but only if the orientation is equal to UIImageOrientationUp):
UIGraphicsBeginImageContextWithOptions(rotatedScaledRect.size, NO, 0.0);
CGContextRef myContext = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(myContext, kCGInterpolationHigh);
CGContextTranslateCTM(myContext,
(rotatedScaledRect.size.width/2),
(rotatedScaledRect.size.height/2));
CGContextConcatCTM(myContext, transformation);
CGContextScaleCTM(myContext, 1.0, -1.0);
CGContextDrawImage(myContext, CGRectMake(-roundf(newImage.size.width / 2), -roundf(newImage.size.height / 2), newImage.size.width, newImage.size.height), [newImage CGImage]);
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
I need to apply CGContextConcatCTM because I have several concatenated transformations to the image.
I've tried several different approaches to no avail.
Thanks in advance for your help.
First of all, excuse me for my english, because it's not my native language. I hope it's not so late to give this answer!
I had a similar problem loading photos from library taken with iPhone or iPod cammera because of this. If that's your case, you can found some info here: https://discussions.apple.com/thread/2495567?start=30&tstart=0, specifically from an answer that says "Apple chose to use the Orientation flag in the EXIF data to inform the program displaying the image as to how to rotate it so the image is presented correctly."
So, for load a photo from library taken with iPhone Cammera, you have to do this:
ALAssetRepresentation *assetRep = [photo defaultRepresentation];
CGImageRef imageRef = [assetRep fullResolutionImage];
UIImage *image = [UIImage imageWithCGImage:imageRef scale:[assetRep scale] orientation:[assetRep orientation]];
where photo is an ALAsset object taken from library.
Well, i hope this helps!

Image Masking+Iphone SDK

I want to mask two images
Image 1:
Image 2:
Now i want to merge this two images like The image2 will come in centre of the image1.
I've read Any idea why this image masking code does not work? and "How to Mask an Image"
But on using this function:-
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
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);
return [UIImage imageWithCGImage:masked];
}
But by using this function I got the output is :-
As far as I can tell the problem is not with maskImage:withMask:. The wrong output you posted is not wrong: where the pixels of image1 are black, image2 is not visible.
The problem is probably or in the functions you used to load image and mask, or in the code producing the graphical output.
Actually it seems to me that you got the right output, but using the wrong colorspace (grayscale without alpha). Check if the argument image you supply is actually in RGBa format, and if the returned UIImage isn't drawn onto some other CGContext using DeviceGray as colorspace.
The other possible cause that comes to my mind is that you inverted image1 and image2. According to the documentation, mask should be scaled up to the size of image (see below) but you have a small image there. This seems reasonable also because image1 is in grayscale, although when I tried to swap image1 and image2 I got image1 unmodified as output.
To run the tests I used the images attached, and then copied & pasted the method -(UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImage as it is.
I used a simple iOS project with one view and an UIImageView inside (with tag 1), and the following code in the controller:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImageView *imageView=(UIImageView *)[self.view viewWithTag:1];
UIImage *im1=[UIImage imageNamed:#"image1"];
UIImage *im2=[UIImage imageNamed:#"image2"];
imageView.image=[self maskImage:im2 withMask:im1];
}
I get the following output (which is right):
If by mistake you invert im1 with im2, you get instead image1 unmodified.

Is this kind of masking possible with UIImage or CGImage API in iOS

I have an UIImage with some text and would like to apply pattern UIImage as masking. Is this possible ?
I understand that with UILabel we can get this kind of gradient using CAGradientLayer. But can this be done if the source is an UIImage ?
The image may have some symbols/pictures etc other than regular characters and hence UIImage. Also i could reuse the image by applying different masking pattern depending on the context.
is this possible ?
Appreciate your help.
EDIT: Thanks for all your answers.
I understand applying the gradient to a text label or creating an image that has text.
But my goal is to get this.--> Click here
i.e. i have a png with some drawing like a flower with transparent background. I want to apply the gradient to the object inside that picture at runtime with a gradient.png as shown in the picture above. Is that possible with masking ?
Thanks
Looks like you should be able to use CGImageMaskCreate:
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
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);
return [UIImage imageWithCGImage:masked];
}
For a longer discussion check out the comment thread here:
http://iosdevelopertips.com/cocoa/how-to-mask-an-image.html
Yes, it is :)
textField.textColor = [UIColor colorWithPatternImage: [UIImage imageNamed:#"rainbowGradient.png"]];
If you want heavy control, Jason Whyne's idea might work. But I like this one, because it's about 8 lines shorter.
Here's just another way to draw an image of text masking something. It's based on kCGBlendModeSourceIn blending mode: you draw text on a clear background and then draw the fill all over the place.
NSString *theString = ...;
UIFont *theFont = ...;
CGSize stringSize = [theString sizeWithFont:theFont];
// The background must be clear (fully transparent), hence NO as the 2nd argument
UIGraphicsBeginImageContextWithOptions(stringSize, NO, 0);
[theString drawAtPoint:CGPointZero withFont:theFont];
// This effectively colorizes the image. Use a pattern color...
[patternColor set];
UIRectFillUsingBlendMode(CGRectMake(0, 0, stringSize.width, stringSize.height), kCGBlendModeSourceIn);
// ... or an image:
[patternImage drawInRect:CGRectMake(0, 0, stringSize.width, stringSize.height) blendMode:kCGBlendModeSourceIn alpha:1.0f];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
sample using mask is fine and works well, but You are leaking.
CGImageMaskCreate and CGImageCreateWithMask do allocate (following "create" -> retain rule)
so You should release mask & image after using:
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
UIImage * result = [UIImage imageWithCGImage:masked];
CGImageRelease(mask);
CGImageRelease(masked);
return result;
As per ADC docs:
...
Return Value
A Quartz bitmap image mask. You are responsible for releasing this object by calling CGImageRelease.

Using CGContext to display a sprite sheet iPhone

So I have a spritesheet in png format, and have already worked out the coordinates for what I want to display. I'm trying to create a method that will return a UIImage when passed the location information on the spritesheet. I'm just not sure how to use the CGContext stuff along with the the coordinates to return an UIImage.
I was looking to CGContextClipToRect because I think that is the way to do it, but I just can't seem to get it to work.
Something like this
CGSize size = CGSizeMake(xSize, ySize);
UIGraphicsBeginImageContext(size);
//CGContextClipToRect(spriteSheet.size, imageRect);
[spriteSheet drawAtPoint:CGPointMake(xPos, yPos)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
returns only what is in the size Context. I need to be able to "move" this size window around the spritesheet if that makes sense.
Any help would be appreciated.
Thanks,
Mike
I think the call you want to use is CGImageCreateWithImageInRect
newImage = [UIImage imageWithCGImage:CGImageCreateWithImageInRect( [spriteSheet CGImage] , imageRect )];
you need to think of your co-ordinates backwards. The CGSize is fixed. Translate your xPos,yPos so that your sprite appears under the window.