iOS 9.3 UIGraphicsImageRenderer showing nil any other option for this? - objective-c

I'm want apply feather effect to the image when cropped but want i render the image using UIGraphicsImageRenderer the render is nil(iOS 9.3) is there any other option for rendering the image in iOS 9.3
This is my code:
UIImage* Img = _myimage;
UIImageView * imageview = [[UIImageView alloc]initWithImage:Img];
[imageview setFrame:CGRectMake(0, 0, Img.size.width, Img.size.height)];
UIBezierPath *aPath;
CAShapeLayer *shapeLayer;
aPath = [UIBezierPath bezierPath];
aPath.contractionFactor = 0.8;
NSValue *mvalue = [_pointsarray objectAtIndex:0];
CGPoint mp2 = [mvalue CGPointValue];
[aPath moveToPoint:mp2];
[aPath addBezierThroughPoints:_pointsarray];
[aPath closePath];
aPath.lineWidth = 2;
shapeLayer = [CAShapeLayer new];
shapeLayer.path=aPath.CGPath;
[shapeLayer setFillColor:[UIColor redColor].CGColor];
[shapeLayer fillColor];
//Here the Renderer is nil in iOS 9.3
UIGraphicsImageRenderer * renderer = [[UIGraphicsImageRenderer alloc] initWithSize:Img.size];
UIImage *shapeImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull context)
{
[shapeLayer renderInContext: context.CGContext];
}];
CIImage * shapeCimage = [[CIImage alloc] initWithImage:shapeImage];
CIFilter * gaussianBlurFilter = [CIFilter filterWithName: #"CIGaussianBlur"];
[gaussianBlurFilter setValue:shapeCimage forKey: #"inputImage"];
[gaussianBlurFilter setValue:#8 forKey:#"inputRadius"];
CIImage * blurredCIImage = [gaussianBlurFilter valueForKey:kCIOutputImageKey];
UIImage * blurredImage = [UIImage imageWithCIImage:blurredCIImage];
UIImageView *maskedImageView = [[UIImageView alloc]initWithImage:blurredImage];
maskedImageView.contentMode = UIViewContentModeScaleAspectFit;
maskedImageView.frame = imageview.frame;
imageview.layer.mask=maskedImageView.layer;
[self.view addSubview:imageview];

UIGraphicsImageRenderer is not available in iOS 9. If you need to target this, you can easily write your own like that:
+(instancetype)LT_imageByDrawingOnCanvasOfSize:(CGSize)size usingBlock:(LTImageDrawingContextBlock)block
{
UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
block( context );
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return theImage;
}

Related

Resize cropped image

Have the similar problem as this post:
How to remove the transparent area of an UIImageView after masking?
but solution doesn't help me, in my case I am cropping image to multi parts, and every part has bounds like parent image had, this is cropping function:
- (UIImage*) maskImage:(CALayer *) sourceLayer toAreaInsidePath:(UIBezierPath*) maskPath;
{
return [self compositeImage:sourceLayer onPath:maskPath usingBlendMode:kCGBlendModeSourceIn];
}
- (UIImage*) compositeImage:(CALayer *) layer onPath:(UIBezierPath*) path usingBlendMode:(CGBlendMode) blend;
{
UIGraphicsBeginImageContext([layer frame].size);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *sourceImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContext([layer frame].size);
[path fill];
[sourceImage drawInRect:[layer frame] blendMode:blend alpha:1.0];
UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return maskedImage;
}
and how I am using it:
- (PuzzlePart *)calculate:(NSDictionary *) item
{
UIBezierPath *path = [self calculatePath:[item objectForKey:#"figure"]];
UIImageView *iView = [[UIImageView alloc] initWithImage:image];
//iView.contentMode = UIViewContentModeCenter;
UIImage *imagePart = [self maskImage:iView.layer toAreaInsidePath:path];
iView.image = imagePart;
return [[PuzzlePart alloc] initWithParams:imagePart lhckID:lifehackID];
}
- (UIBezierPath *)calculatePath:(NSArray *) points {
UIBezierPath *path = [UIBezierPath bezierPath];
NSDictionary *point = [points objectAtIndex:0];
[path moveToPoint:CGPointMake([point[#"x"] intValue], [point[#"y"] intValue])];
for (int i = 1; i < [points count]; i++) {
point = [points objectAtIndex:i];
[path addLineToPoint:CGPointMake([point[#"x"] intValue], [point[#"y"] intValue])];
}
[path closePath];
return path;
}
and place it:
- (void)placeItems
{
for (PuzzlePart *part in puzzleParts) {
UIImage *imagePart = [part imagePart];
CGRect newRect = [self cropRectForImage:imagePart];
UIImage *image = [self imageWithImage:imagePart convertToSize:newRect.size];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
//imageView.contentMode = UIViewContentModeCenter;
imageView.center = CGPointMake([self getRandomNumberBetween:0 to:self.view.frame.size.width],
[self getRandomNumberBetween:0 to:self.view.frame.size.height]);
[self.view addSubview:imageView];
while ([self viewIntersectsWithAnotherView:self.view chosenView:imageView]) {
viewPositionMovingStep++;
[self placeItem:self.view:imageView];
}
}
[self startCountdown];
}
[self cropRectForImage:imagePart] is the same method from post I marked
and this what I have after:
any ideas? Thank you!

Image with rounded corners and border

Trying to get an image with rounded corners and stroke,
but there is something I do wrong, because app hangs during this:
- (UIImage *)roundedCornerImage:(NSInteger)radius{
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0);
CGRect box = CGRectInset((CGRect){CGPointZero, self.size}, self.size.width * 0.9f, self.size.height * 0.9f);
UIBezierPath *ballBezierPath = [UIBezierPath bezierPathWithOvalInRect:box];
[[UIColor blackColor] setStroke];
[ballBezierPath setLineWidth:4.0];
[ballBezierPath stroke];
[[UIBezierPath bezierPathWithRoundedRect:(CGRect){CGPointZero, self.size}
cornerRadius:radius]addClip];
[self drawInRect:(CGRect){CGPointZero, self.size}];
UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
Forget messing with the layer, it's a performance killer in scroll views. Just generate a new image instead:
+(UIImage *)makeRoundedImage:(UIImage *)image withRadius:(CGFloat)radius
{
CGRect itemFrame = CGRectMake(0, 0, radius*2, radius*2);
// The source image
UIImageView *imageView = [UIImageView new];
imageView.frame = itemFrame;
imageView.contentMode = UIViewContentModeScaleToFill;
[imageView setImage:image];
imageView.layer.cornerRadius = radius;
imageView.layer.masksToBounds = YES;
// Make an image of our client item
UIGraphicsBeginImageContextWithOptions(itemFrame.size, NO, 0.0);
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Fini
return returnImage;
}
Just use
[imageView.layer setCornerRadius:5.0f];
[imageView.layer setBorderWidth:5.0f];
Don;t forget to #import Quartzcore;

Render a single UIImage and rotation has to be applied

I have rendered few UIImage objects using CGContextDrawImage. But when i apply rotation to the image, it is not applied and the view disappears.
code here
-(void )renderImage: (ItemView *)array
{
NSArray *selectedImages = self.slideView.selectedView.subviews;
CGSize combinedSize = CGSizeMake(0, 0);
for (int i = 0; i < [selectedImages count]; ++i) {
CGSize sourceSize = [selectedImages[i] size];
NSLog(#"sdfsd %f %f ", sourceSize.width, sourceSize.height);
combinedSize.width = MAX(combinedSize.width, sourceSize.width);
combinedSize.height += sourceSize.height;
}
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
{
CGContextTranslateCTM(context, 0, 768);
CGContextScaleCTM(context, 1,-1);
for (int i = 0; i < [selectedImages count]; ++i) {
UIImageView *imageview = selectedImages[i];
UIImage *sourceImage = imageview.image;
CGContextSaveGState(context);
float radians1 = atan2(imageview.transform.a, imageview.transform.b);
CGFloat angle = [(NSNumber *)[imageview valueForKeyPath:#"layer.transform.rotation.z"] floatValue];
printf("\n radians %f",radians1);
printf("\n angle %f",angle);
CGContextRotateCTM(context, radians(angle));
CGContextDrawImage(context, imageview.frame, imageview.image.CGImage);
CGContextRestoreGState(context);
//CGContextDrawImage(context, imageview.frame, imageview.image);
}
}
UIImage *combinedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(combinedImage, nil, nil, nil);
}
Thanks,
Any help would be appreciated
Let's say you have an array of source images:
NSArray *sourceImages = ...;
// each element of sourceImages is a UIImage
Now you want to take the first count images from the array and concatenate them vertically into a new image. Start by figuring out the size of the combined image:
CGSize combinedSize = CGSizeMake(0, 0);
for (int i = 0; i < count; ++i) {
CGSize sourceSize = [sourceImages[i] size];
combinedSize.width = MAX(combinedSize.width, sourceSize.width);
combinedSize.height += sourceSize.height;
}
Next, create a graphics context of that size:
UIGraphicsBeginImageContextWithOptions(combinedSize, NO, 0); {
Now draw each component image into the graphics context at the appropriate position:
CGFloat y = 0;
for (int i = 0; i < count; ++i) {
UIImage *sourceImage = sourceImages[i];
[sourceImage drawAtPoint:CGPointMake(0, y)];
y += sourceImage.size.height;
}
Finally, create the combined image from the context and dispose of the context:
}
UIImage *combinedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Read Drawing and Printing Guide for iOS - Drawing and Creating Images for more information.
I cracked the answer . # rob mayoff : Thanks much who helped me out.
code here
//code to render group of images excluding the image which has been selected in a particular view
-(void )renderImage: (ItemView *)selectedItem
{
NSArray *selectedImages = self.slideView.selectedView.subviews;
int selectedItemIndex = [selectedImages indexOfObject:selectedItem];
if(selectedItem.image==nil){
[selectedItem loadImageFromFile];
}
// first set
UIGraphicsBeginImageContextWithOptions(self.slideView.selectedView.frame.size, NO, 0);
for (int i = 0; i < selectedItemIndex; ++i) {
if([selectedImages[i] isKindOfClass:[ItemView class]]){
ItemView *imageview = (ItemView *)selectedImages[i];
CGAffineTransform transform = imageview.transform;
imageview.transform = CGAffineTransformIdentity;
UIImage *image = [[UIImage alloc] initWithContentsOfFile:imageview.filename];
UIImageView *renderImageView = [[UIImageView alloc] initWithImage:image]; //[imageview copy];
renderImageView.frame = imageview.frame;
renderImageView.bounds = imageview.bounds;
imageview.transform = transform;
renderImageView.transform = transform;
renderImageView.center = CGPointMake(imageview.frame.size.width/2,imageview.frame.size.height/2);
UIView *view = [[UIView alloc] initWithFrame:renderImageView.frame];
view.backgroundColor = [UIColor clearColor];
[view addSubview:renderImageView];
[renderImageView release];
[image release];
imageview.image = nil;
UIGraphicsBeginImageContext(imageview.frame.size);
CGContextRef context1 = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context1];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[view release];
[result drawAtPoint:imageview.frame.origin];
}
}
UIImage *combinedImage1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//UIImageWriteToSavedPhotosAlbum(combinedImage1, nil, nil, nil);
if (groupBgImage1) {
[groupBgImage1 removeFromSuperview];
[groupBgImage1 release];
groupBgImage1 = nil;
}
groupBgImage1 = [[UIImageView alloc] initWithImage:combinedImage1];
[self.slideView.selectedView insertSubview:groupBgImage1 belowSubview:selectedItem ];
// second set
UIGraphicsBeginImageContextWithOptions(self.slideView.selectedView.frame.size, NO, 0);
for (int i = selectedItemIndex+1; i < [selectedImages count]; ++i) {
if([selectedImages[i] isKindOfClass:[ItemView class]]){
ItemView *imageview = (ItemView *)selectedImages[i];
CGAffineTransform transform = imageview.transform;
imageview.transform = CGAffineTransformIdentity;
UIImage *image = [[UIImage alloc] initWithContentsOfFile:imageview.filename];
UIImageView *renderImageView = [[UIImageView alloc] initWithImage:image]; //[imageview copy];
renderImageView.frame = imageview.frame;
renderImageView.bounds = imageview.bounds;
imageview.transform = transform;
renderImageView.transform = transform;
renderImageView.center = CGPointMake(imageview.frame.size.width/2,imageview.frame.size.height/2);
UIView *view = [[UIView alloc] initWithFrame:renderImageView.frame];
view.backgroundColor = [UIColor clearColor];
[view addSubview:renderImageView];
[renderImageView release];
[image release];
imageview.image = nil;
UIGraphicsBeginImageContext(imageview.frame.size);
CGContextRef context1 = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context1];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[view release];
[result drawAtPoint:imageview.frame.origin];
}
}
UIImage *combinedImage2 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(combinedImage2, nil, nil, nil);
if (groupBgImage2) {
[groupBgImage2 removeFromSuperview];
[groupBgImage2 release];
groupBgImage2 = nil;
}
groupBgImage2 = [[UIImageView alloc] initWithImage:combinedImage2];
[self.slideView.selectedView insertSubview:groupBgImage2 aboveSubview:selectedItem ];
}

iOS - Merging two images of different size

I'm facing the following problem : I have to merge two images A and B to create a new image C as a result of the merging.
I already know how to merge two images but in this case my goal is a little bit different.
I would like that image A will be the background for Image B.
For instance if image A size is 500x500 and image B size is 460x460 I would like that image C (the image result of the merging) will be 500x500, with image B (460x460) centered in it.
Thanks in advance for any help or suggestion
This is what I've done in my app, but without using UIImageView:
UIImage *bottomImage = [UIImage imageNamed:#"bottom.png"]; //background image
UIImage *image = [UIImage imageNamed:#"top.png"]; //foreground image
CGSize newSize = CGSizeMake(width, height);
UIGraphicsBeginImageContext( newSize );
// Use existing opacity as is
[bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Apply supplied opacity if applicable
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.8];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
If the image already has opacity, you do not need to set it (as in bottomImage) otherwise you can set it (as with image).
After this UIImage is created then you can embed it in your UIImageView
UPDATE: Thanks to Ahmet AkkoK - for Swift (2.2) users blend mode macro has changed. CGBlendMode .kCGBlendModeNormal is replaced with CGBlendMode.Normal
Hey i got multiple images add same background with different foreground
This is my code
UIImage *bottomImage = [UIImage imageNamed:#"photo 2.JPG"]; //background image
UIImage *image = [UIImage imageNamed:#"photo 3.JPG"]; //foreground image
UIImage *image1 = [UIImage imageNamed:#"photo 4.JPG"]; //foreground image
UIImage *image2 = [UIImage imageNamed:#"photo 5.JPG"]; //foreground image
CGSize newSize = CGSizeMake(320, 480);
UIGraphicsBeginImageContext( newSize );
// Use existing opacity as is
[bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Apply supplied opacity if applicable
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.4];
[image1 drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.3];
[image2 drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.2];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
resultView = [[UIImageView alloc] initWithImage:newImage];
resultView.frame = CGRectMake(0, 0,320,460);
[self.view addSubview:resultView];
Swift version
Copy/Paste to Playground
var bottomImage:UIImage = UIImage(named:"avatar_4.png") //background image
var imageTop:UIImage = UIImage(named:"group_4.png") //top image
var newSize = CGSizeMake(bottomImage.size.width, bottomImage.size.height)
UIGraphicsBeginImageContext( newSize )
bottomImage.drawInRect(CGRectMake(0,0,newSize.width,newSize.height))
// decrease top image to 36x36
imageTop.drawInRect(CGRectMake(18,18,36,36), blendMode:kCGBlendModeNormal, alpha:1.0)
var newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
var imageData = UIImagePNGRepresentation(newImage)
To load images from playground:
Open playground file and create there folder Resources
copy images to this folder
Just made quick paste function for those of you who wanted to use Srikar Appal answer. (if in case background & foreground images are of different sizes)
- (UIImage *) mergeImages:(NSString *)bgImageFileName foreGround:(NSString *)fgImageFileName {
UIImage *bottomImage = [UIImage imageNamed:bgImageFileName]; //background image
UIImage *image = [UIImage imageNamed:fgImageFileName]; //foreground image
CGSize newSize = CGSizeMake(bottomImage.size.width, bottomImage.size.height);
UIGraphicsBeginImageContext(newSize);
// Use existing opacity as is
[bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Apply supplied opacity if applicable
// Change xPos, yPos if applicable
[image drawInRect:CGRectMake(11,11,image.size.width,image.size.height) blendMode:kCGBlendModeNormal alpha:1.0];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
in Swift:
let bottomImage = UIImage(named: "Bottom_Image.png")
let frontImage = UIImage (named: "Front_Image.png")
let size = CGSize(width: 67, height: 55)
UIGraphicsBeginImageContext(size)
let areaSize = CGRect(x: 0, y: 0, width: size.width, height: size.height)
let frontImageSize = CGRect(x: 14, y: 3, width: 40, height: 40)
bottomImage!.drawInRect(areaSize, blendMode: CGBlendMode.Normal, alpha: 1.0)
frontImage!.drawInRect(frontImageSize, blendMode: CGBlendMode.Normal, alpha: 1.0)
let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
Thanks #Srikar Appal for iOS soultion.
For anyone who is looking for merge in OS X:
- (NSImage *) mergeImages:(NSString *)bgImageFileName foreGround:(NSString *)fgImageFileName {
NSImage *bottomImage = [NSImage imageNamed:bgImageFileName];
NSImage *overlayedImage = [NSImage imageNamed:fgImageFileName];
NSSize newSize = NSMakeSize(bottomImage.size.width, bottomImage.size.height);
NSSize overlaySize = NSMakeSize(newSize.width/2, newSize.height/2); //change the size according to your requirements
NSImage *newImage = [[NSImage alloc] initWithSize:newSize];
[newImage lockFocus];
[bottomImage drawInRect:NSMakeRect(0, 0, newSize.width, newSize.height)];
[overlayedImage drawInRect:NSMakeRect(newSize.width-overlaySize.width, 0, overlaySize.width, overlaySize.height)]; //set the position as required
[newImage unlockFocus];
return newImage;
}
You can go with another trick as described below:
Add first image to a imageView.
Add second image to another imageView.
Add both the above imageViews in a single main imageView and access the combined image by property of imageView : mainImageView.image
Have a look at the code below :
CGRect rect= investmentDetailTblView.frame;
int rows = investmentDetailArray.count;
CGFloat heightFinal = 5;
CGRect frame1;
for (int i=0; i<rows; i++)
{
frame1 = [investmentDetailTblView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
CGFloat height = frame1.size.height;
heightFinal = heightFinal + height;
}
rect.size.height = heightFinal;
investmentDetailTblView.frame=rect;
UIImageView *imageViewTable = [[UIImageView alloc] init];
[imageViewTable setFrame:CGRectMake(0, 0, frame1.size.width, heightFinal)];
[investmentDetailTblView reloadData];
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
UIGraphicsBeginImageContextWithOptions(investmentDetailTblView.bounds.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(investmentDetailTblView.bounds.size);
[investmentDetailTblView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageViewTable.image = image; //Adding the table image to the image view.
CGRect frame=CGRectMake(0, heightFinal+5, investmentDetailTblView.frame.size.width, 20) ;
UIView *footerView=[DataStore kkrLogoView];
footerView.frame=frame;
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
UIGraphicsBeginImageContextWithOptions(footerView.frame.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(footerView.frame.size);
[footerView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *kkrLogoImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageViewFooter = [[UIImageView alloc] init];
[imageViewFooter setFrame:CGRectMake(0, heightFinal, footerView.frame.size.width, footerView.frame.size.height)];
imageViewFooter.image = kkrLogoImage; //Adding the footer image to the image view.
UIImageView *mainImageView = [[UIImageView alloc] init];
[mainImageView setFrame:CGRectMake(0, 0, frame1.size.width, (heightFinal+footerView.frame.size.height))];
[mainImageView addSubview:imageViewTable];
[mainImageView addSubview:imageViewFooter];
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
UIGraphicsBeginImageContextWithOptions(mainImageView.frame.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(mainImageView.frame.size);
[mainImageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Render large CATiledLayer into smaller area

I have a CATiledLayer of size 4096 x 4096 which I want to render into a PNG of size 1024 x 1024
this isnt doing it...
-(NSData *)createPNGFormat
{
UIGraphicsBeginImageContext(CGSizeMake(1024, 1024));
tiledLayer.transform = CATransform3DMakeScale(0.25, 0.25, 1.0);
[tiledLayer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return UIImagePNGRepresentation(image);
}
Any ideas on how to do this?
[First Hack] Brute Force , Render tile by tile. This works (slowly)
-(UIImage *)renderTileX:(NSInteger)xpos tileY:(NSInteger)ypos scale:(CGFloat)ascale
{
CGSize tiledsize = tiledLayer.tileSize;
CGRect tiledframe = tiledLayer.bounds;
CALayer *container = [CALayer layer];
container.frame = CGRectMake(0, 0, tiledsize.width,tiledsize.height);
UIGraphicsBeginImageContext(tiledsize);
[container addSublayer:tiledLayer];
tiledLayer.frame = CGRectMake(-tiledsize.width*xpos,-tiledsize.height*ypos, tiledframe.size.width, tiledframe.size.height);
[container renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[tiledLayer removeFromSuperlayer];
CGFloat fsize = tiledsize.width*ascale;
CGRect apicrect = CGRectMake(0,0,fsize,fsize);
UIGraphicsBeginImageContext(apicrect.size);
[image drawInRect:apicrect];
UIImage *thumb = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return thumb;
}
-(UIImage *)renderTiledLayer
{
UIGraphicsBeginImageContext(CGSizeMake(1024, 1024));
for (NSInteger x = 0 ; x<4; x++) {
for (NSInteger y = 0; y < 4; y++) {
NSLog(#"render %d:%d",x,y);
UIImage *tile = [self renderTileX:x tileY:y scale:0.25];
[tile drawAtPoint:CGPointMake(x*256, y*256)];
}
}
UIImage *fimage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return fimage;
}
[Using the Google...] The better way
-(UIImage *)createThumb
{
UIGraphicsBeginImageContext(CGSizeMake(1024, 1024));
CGContextScaleCTM(UIGraphicsGetCurrentContext(), 0.25, 0.25);
[tiledLayer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *fimage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return fimage;
}