I am struggling getting Image Insets to work when drawing to an off screen buffer.
Using the resizableImageWithCapInsets: on an UIImage directly setImage: into a button works fine for me:
UIImage * base = [UIImage imageNamed:#"button.png"];
UIImage * img = [base resizableImageWithCapInsets:UIEdgeInsetsMake(20,20,20,20)];
[self setImage:img forState:UIControlStateNormal];
As shown below (left is raw scaling, right is scaled with insets):
So the right one is fine - the lines top/botton/left/right are equally spaced. So far so good.
Now if I try the very same thing with an image that is drawn and then captured to an off screen buffer with:
UIImage * base = [UIImage imageNamed:#"button.png"];
base = [base resizableImageWithCapInsets:UIEdgeInsetsMake(20,20,20,20)];
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
ctx = UIGraphicsGetCurrentContext();
CGContextDrawImage(ctx, CGRectMake(0,0,self.bounds.size.width,
self.bounds.size.height), [base CGImage]);
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setImage:img forState:UIControlStateNormal];
I get below (again left is raw scaling, right is with insets):
.
So here it seems that the insets are ignored.
Anyone any suggestions as to what is going wrong here ? Fully functional example at http://people.apache.org/~dirkx/insetSample.zip and just the key code at http://pastebin.com/rm8h6YFV.
Any and all suggestions appreciated.
Dw
I would guess that stretchable UIImages are handled at a higher level than Quartz2D and so using CGContextDrawImage is not going to work.
You could try using -[UIImage drawInRect] instead. This will draw to the current UIGraphics context, which is your bitmap context that you create in your code snippet.
The relevant line is:
[base drawInRect:CGRectMake(0,0,self.bounds.size.width,
self.bounds.size.height)];
Related
I'm attempting to create a UIImage and save it to the photo gallery, the image gets created but it's just a plane white with no color what so ever. Any ideas?
UIGraphicsBeginImageContext(CGSizeMake(320,420));
CGContextRef ctx = UIGraphicsGetCurrentContext();
UIImage *image = [[UIImage alloc] init];
[image drawInRect:CGRectMake(0, 0, 100, 100)];
UIImage *newImage;
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIImageWriteToSavedPhotosAlbum(newImage, self, #selector(image:didFinishSavingWithError:ctx:), nil);
Also just to add to the above. I added this line:
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
And now I get a grey image, still no rectangle, but it's something different so thought it might help
What UIImage are you trying to show?, this code only initialized a space of memory but it's filled with nothing, use [UIImage imageNamed:#"..."]; where the string is some file the resources for your project. Then once you have opened and drawn the image in the context you will be able to draw a string or whatever over it.
Also make sure that you close the context once you have gotten the image from it.
I want to know, how can I erase a custom rect (with, for example, an UIView in IB or something else) of an UIImageView in order to display an other UIImageView positioned underneath.
I didn't manage to do it using some response in the forum...
This will clear a rect in an image:
- (UIImage *)clearRect:(CGRect)rect inImage:(UIImage *)image {
if (UIGraphicsBeginImageContextWithOptions != NULL)
UIGraphicsBeginImageContextWithOptions([image size], NO, 0.0);
else
UIGraphicsBeginImageContext([image size]);
CGContextRef context = UIGraphicsGetCurrentContext();
[image drawInRect:CGRectMake(0.0, 0.0, [image size].width, [image size].height)];
CGContextClearRect(context, rect);
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
Just load your image and clear the rects before assigning it to the image view:
UIImage *image = [UIImage imageNamed:#"Image.png"];
UIImage *maskedImage = [self clearRect:CGRectMake(10.0, 10.0, 50.0, 50.0) inImage:image];
[imageView setImage:maskedImage];
probably not the best solution but you can do the other way and take the 4 parts around the rect separately and combine them afterwards without the inner rect. You would repeat this as long as you have rect's to crop out.
You cannot clear the UIImageView itself because this just draws the UIImage. So you have erase the rect in the UIImage. Create a bitmap context, draw the image into it. Erase the part you want to "see through" with CGContextClearRect. When create a new new image from the bitmap context.
I used the codes below to rotate an UIImage
double angle = -90;
NSData *imageData = [NSData dataWithContentsOfFile:sss];
UIImage *image =[UIImage imageWithData:imageData];
CGSize s = {image.size.width, image.size.height};
UIGraphicsBeginImageContext(s);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, 0,image.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextRotateCTM(ctx, 2*M_PI*angle/360);
CGContextDrawImage(ctx,CGRectMake(0,0,image.size.width, image.size.height),image.CGImage);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[myUIImageView setImage:newImage];
but nothing displays on myUIImageView.
If there is anything wrong?
Welcome any comment
Thanks
interdev
If you're going to be rotating the image 90 degrees, you should swap the width and height when you create the image context:
CGSize s = {image.size.height, image.size.width};
This way, there's enough space to draw the fully-transformed image. Attempting to draw an image into a rectangle which exceeds the bounds of a graphics context will just result in nothing being drawn.
P.S. I recommend using a CGBitmapContext instead of UIGraphicsBeginImageContext(), as the former is thread-safe, which means you'd be able to do your image manipulations on a background thread if you so chose.
Ive an image with particular resolution appearing on Iphone screen. I need to resize that image by getting info. as an alert from user(Width and height). Cud anyone help me with block of code for this????
WARNING: code typed in answer box, not tested. It's pretty close, though.
NSSize newSize = [self getSizeFromUser]; // you have to write this part.
CGRect theRect = CGRectMake (0, 0, newSize.width, newSize.height);
// Put image into new context
UIGraphicsBeginImageContext (newSize);
[theImage drawInRect: theRect];
//get the image from the context
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
[[compositeImage retain] autorelease];
UIGraphicsEndImageContext();
I need to draw a series of PNGs into a CGContext so I can blend them together:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetBlendMode(context, kCGBlendModeOverlay);
Currently I have my app working based on just drawing each image as a UIImageView and adding them as a subview to the view file via: [self addSubview:someImageView] ...but this doesn't allow for blending mode manipulation, right?
Currently the UIImageView vars are being assigned via:
someImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image-name.png"]];
So I've tried replacing those with either of these with no luck:
[[UIImage imageNamed:#"image-name.png"] drawInRect:rect blendMode:kCGBlendModeOverlay alpha:1.0];
and this one needs a CGImage which I'm not sure how to make with the PNGs:
CGContextDrawImage(context, rect, someCGImage);
So what am I missing? These aren't being triggered by any interaction, they just need to load/draw when the app loads.
Thanks for any leads. :)
You don't need to be using UIImageViews.
Instead, bracket your drawing between calls to UIGraphicsBeginImageContext and UIGraphicsEndImageContext.
For example (code not tried):
UIImage* uiimage = [UIImage imageNamed:#"image-name.png"];
UIImage* uiimage2 = [UIImage imageNamed:#"other-image-name.png"];
CGSize size = uiimage.size;
UIGraphicsBeginImageContext(size);
[uiimage drawAtPoint:CGPointZero blendMode:kCGBlendModeOverlay alpha:1.0];
[uiimage2 drawAtPoint:CGPointZero blendMode:kCGBlendModeOverlay alpha:1.0];
UIImage* blendedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
If you want to use CG calls, call:
CGContextRef context = UIGraphicsGetCurrentContext();
to get the context ref.