Loading UIview background fastly using image - iphone

Iam developing one application.In that i want to set the uiview background as image.That image size is 1.6 mb.I followed the below code.
UIGraphicsBeginImageContext(self.view.frame.size);
[[UIImage imageNamed:#"image.png"] drawInRect:self.view.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.view.backgroundColor = [UIColor colorWithPatternImage:image];
But it takes more time compared to small size image.So please help me how to load 3mb size of image also like as small size of image.

You could do the drawing operations on a background queue, so it won't freeze the UI:
CGRect imgRect = self.view.bounds;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
UIGraphicsBeginImageContext(imgRect.size);
[[UIImage imageNamed:#"image.png"] drawInRect:imgRect];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIColor* bgcolor = [UIColor colorWithPatternImage:image];
dispatch_async(dispatch_get_main_queue(), ^{
self.view.backgroundColor = bgcolor;
});
});
Also optimize the image by using the tool ImageOptim.

Its best if you resize image and then add in Application bundle to execute faster.
here I think there is no need get image firstly for resizing for UIView s pattern image in background.
You can solve memory issue like this:
NSString *imgfile = [[NSBundle mainBundle] pathForResource:#"image" ofType:#"png"];
UIImage *currentImage = [UIImage imageWithContentsOfFile:imgfile];
self.view.backgroundColor = [UIColor colorWithPatternImage:currentImage];
Refer ios-imagenamed-vs-imagewithcontentsoffile link.
EDIT : Use #phix23 answer for smooth UI

Related

Take a snapshot of a PKAddPassesViewController's view

I'm trying to take a snapshot of the view displayed when the user is prompted to add a pass.
The goal is being able to generate an image from a given pkpass
I was hoping something like this could work:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"columbus" ofType:#"pkpass"];
PKPass *pass = [[PKPass alloc] initWithData:[NSData dataWithContentsOfFile:filePath] error:nil];
PKAddPassesViewController *pkAddPassesViewController = [[PKAddPassesViewController alloc] initWithPass:pass];
[self presentViewController:pkAddPassesViewController animated:YES completion:^(){
UIImage *image = [pkAddPassesViewController.view captureView];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[self.view addSubview:imageView];
}];
With captureView being:
- (UIImage *)captureView
{
CGRect screenRect = self.bounds;
UIGraphicsBeginImageContext(self.bounds.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor clearColor] set];
CGContextFillRect(ctx, screenRect);
[self.layer renderInContext:ctx];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Guess what? I was wrong:
I tried:
Using the completion callback and the animationFinished callback
Setting the hidden property
Using a timer to make sure the pass was visible on screen when the screenshot was taken
Taking a snapshot of the parent view
I ran out of ideas, so any suggestion is appreciated
Thanks in advance
Oh, I've uploaded a minimal project here:
https://github.com/framp/demo-capturing-passbook
EDIT:
I'm able to take a snapshot of other views and I can load other UIImage just fine with the code above.
The UIImage which is returned is a blank image
Try this, this might work for you.
UIGraphicsBeginImageContext(self.view.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *newImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData=UIImagePNGRepresentation(reportImage);
The capture image code is good. Try with : [self.view.superview addSubview:imageView]; in the completion block instead of [self.view addSubview:imageView];
You can try this code if that work for you. Give the Coordinates which you want to capture and thats it. It will save your file in image album. It may give a warning but it works.
UIGraphicsBeginImageContext(CGSizeMake(320, 380));
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
I think pkAddPassesViewController is not fully loaded when you taken snapshot. So my suggestion is to take screenshot after some delay.
I hope it will work.

Scale image to fit tile

Let me start with my code:
UIImage *tempImage = [UIImage imageNamed:#"TileMap.gif"];
[tempImage drawInRect:CGRectMake(0, 0, tileSize, tileSize)];
mapLabels[w][h] = [[UILabel alloc] initWithFrame:CGRectMake(cursor.x, cursor.y, tileSize, tileSize)];
mapLabels[w][h].text = [NSString stringWithFormat:#"%d", map[w][h]];
mapLabels[w][h].backgroundColor = [UIColor colorWithPatternImage: tempImage];
mapLabels[w][h].textAlignment = UITextAlignmentCenter;
[self.view addSubview:mapLabels[w][h]];
I made a map of tiles out of UILabels. I wanted to put an Image on the labels so I used the colorWithPatternImage. It works but my tile pictures are very high resolution and my UILabel tiles can be any size so I need the image to be the same size. What I am currently trying to do to scale it with the drawInRect is not working, any tips?
There is a scale property for UIImages. You could try something like:
tempImage.scale = mapLabels[w][h].tileSize.x / tempImage.tileSize.x

Saving two Overlapping UIImage

I am trying to build a photo frame application on iphone. I made the frame it is transparent in png formate, then by choosing photos and was placed behind the frame layer in the interface builder.
In interface builder they are placed well and fit well. Now my problem is how can i save them into one picture.
Here is the code i have, but the saving part keep crashing.
-(IBAction) saveImage:(id)sender{
imagefront .backgroundColor = [UIColor clearColor]; //This sets your backgroung to transparent.
imagefront.opaque = NO;
[imageView bringSubviewToFront:imagefront];
UIImage *overlappedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(overlappedImage, self, #selector(imageSavedToPhotosAlbum: didFinishSavingWithError: contextInfo:), nil);
}
Imagefront is the photoframe while imageView is the photo.
Thank you.
Your current approach is incorrect. You will need to do this to get the image.
UIGraphicsBeginImageContext(imageView.frame.size);
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsGetCurrentContext();
This is assuming that imageView has imageFront as its subview as suggested by the code you've posted.

CALayer - backgroundColor flipped?

I'm creating a CALayer like this:
UIColor *color = [UIColor colorWithPatternImage:[UIImage imageNamed:#"MyPattern.png"]];
backgroundLayer = [[CALayer alloc] init];
[backgroundLayer setBackgroundColor:[color CGColor]];
[[self layer] addSublayer:backgroundLayer];
For some reason, the pattern is drawn upside down. I've already tried setting geometryFlipped and applying sublayer transforms, but it doesn't work.
Using [backgroundLayer setTransform:CATransform3DMakeScale(1.0, -1.0, 1.0)]; actually does work.
I would rather use this method:
CALayer *backgroundLayer = [CALayer layer];
backgroundLayer.frame = CGRectMake(50, 50, 200, 200);
UIImage *img = [UIImage imageNamed:#"MyPattern.png"];
CGImageRef imgRef = CGImageRetain(img.CGImage);
backgroundLayer.contents = (id) imgRef;
[self.layer addSublayer:backgroundLayer];
This will provide image content inside the layer and it fits automatically, so it works great for backgrounds. Im not sure why your method isnt working, sorry about that, but I thought it would be nice to provide you with this method.
Instead of using CATransform3DMakeScale you can flip image yourself:
UIImage* img = [UIImage imageNamed:#"MyPattern.png"];
img = [UIImage imageWithCGImage:img.CGImage
scale:img.scale
orientation:UIImageOrientationDownMirrored];
UIColor* color = [UIColor colorWithPatternImage:img];
…
This works fine for me.
Or you can go further and actually redraw the image.
- (UIImage*)flipImage:(UIImage*)image {
UIGraphicsBeginImageContext(image.size);
CGContextDrawImage(UIGraphicsGetCurrentContext(),CGRectMake(0.,0., image.size.width, image.size.height),image.CGImage);
UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Details why it can be useful are in this answer.

How to make an tiled background like on the web?

On the iPhone, how could I achieve the same tiled background effect?
For example, I have an pattern image which I want to repeat only horizontally. Would I have to go the route in -drawRect: by myself and loop over to draw the pattern, or is there a convenient method to do that?
You can set the backgroundColor of the UIView with a pattern using the following snippet:
UIImage *image = [UIImage imageNamed:#"pattern.png"];
myView.backgroundColor = [UIColor colorWithPatternImage:image];
The image will automatically be tiled for you to cover the area.
Claus
- (void)drawRect:(CGRect)rect
{
CGContextRef currentContext = UIGraphicsGetCurrentContext();
UIImage* img = [UIImage imageNamed:#"transparency.png"];
CGContextDrawTiledImage(currentContext, CGRectMake(0, 0, 12, 12), [img CGImage]);
}
In this example "transparency.png" is a 12x12 image.