Show image of 10000x8000 pixels in iOS app - ios

I'm trying to show image in my iOS APP.The image is of 10000x8000, which is much higher than iPhone's screen resolution, if I add it to UIImageView ,the APP will receive memory warnings and lead to crash.Can any one give me a advice about how to deal with it? Thanks a lot.

This is the sample app from apple which displays large size image, it uses TileImageView scale the image and reuse tiles according to present zoom.
https://developer.apple.com/library/ios/samplecode/LargeImageDownsizing/Introduction/Intro.html
Or if you simple want scale down the image, you could use this.
+ (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}

This is just a side note and not an answer.
#AmitTandel's answer will surely help you but,
remember, you should not always request for this high resolution image instead you should implement a logic which stores this high resolution image to somewhere after reducing it using #Amit's answer. And then at the time of re-requesting for the same image url, you should first look up in to your stored directory, if that image not exist only then you may request for an image.
But yes, I'm not suggesting you to follow my answer as you will require to download this very high resolution sized image (which is actually none of use), so if you're getting this image from your server, you can ask them to give you reduced size for images. I've heard that, they can reduce images to different sizes to help apps showing specific images at variant places.

Related

App crashed when I display a large image by UIImageView

I set a image with 10000 * 10000 pixels to UIImageView from network by SDWebImage, and App crashed because it allocated too much memory. I tried to resize the image that had been loaded by SDWebImage, so I add the code below:
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, CGRectMake(0, 0, size.width, size.height));
CGContextSetInterpolationQuality(context, 0.8);
[self drawInRect:drawRect blendMode:kCGBlendModeNormal alpha:1];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Although the image size was smaller, my app crashed due to the same reason.
It seems that there are some rendering action during the resizing action, the memory would rose to 600M and fell to 87M in a little while.
How can I resize a image without rendering?
It seems that display the image by UIWebView did not exist the problem. How it works?
Any help and suggestions will be highly appreciable。
Resolution:
https://developer.apple.com/library/ios/samplecode/LargeImageDownsizing/
The Resolution does work for jpg but not for png
You can't unpack the image into memory because it's too big. This is what image tiling is for, so you would download a set of tiles for the image based on the part you're currently looking at (the zoom position and scale).
I.e. if you're looking at the whole image you get 1 tile which is zoomed out and therefore low quality and small size. As you zoom in you get back other small size images which show less of the image 'area'.
The web view is likely using the image format to download a relatively small image size that is a scaled down version of the whole image, so it doesn't need to unpack the whole image to memory. It can do this because it knows your image is 10,000x10,000 but that it is going to be displayed on the page at 300x300 (for example).
Did you try to use : UIImageJPEGRepresentation (or UIImagePNGRepresentation)
You can make your image size smaller with it.

UIImage displaying incorrectly in UIImageView

This might not be the proper place to ask this since it seems the issue is with the actual image, but I'm hoping someone here has seen this issue before.
I am loading images from a server. First I take the photo, upload it from the server and then view it in a different part of the application. This is when I saw that the aspect ratio of any image I had just uploaded was way off. See image one below. Images that I had uploaded in the past did not have these issues. The difference is that I had to pull the previous images into photoshop to rotate them.
I got my node.js server to orient them for me but then when I load them up in the UIImageView they are squished and stretched. Viewing them in the browser or on my computer shows them as normal. Out of curiosity I opened one in photoshop, did not manipulate it at all and saved it out. When I uploaded it to my server and viewed it on the iPhone again it looked as it should. See the second image below.
Again all other images load just fine but the ones that did not go through Photoshop come out all wonky.
Any thoughts? Thanks in advance for your help.
EDIT : When viewing the photos in the browser they are also stretched when resized. When I click to view full size and then click again to view the scaled to fit the screen they look fine. Just wanted to throw some more info out there to see if anyone knows what's up.
try this code,
- (UIImage*)imageWithImage:(UIImage*)images
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[images drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
and then set imageview imaeg this way
imageView.image = [self imageWithImage:mi.imageView.image scaledToSize:CGSizeMake(78, 78)];
I'm not sure what the problem is exactly but I found a sort of solution.
First off I tried it from a 4s to make sure it wasn't an issue with my phone and I got the same result. I found out that if I strip the exif data out of the image it seems to work just fine. What I ended up doing is using a package on my server, GraphicsMagic, and running the images through autoOrient. After this is done and saved out to disk the images load just fine in both the browser and on the iPhone. If anyone has any explanation of what would cause that, that would be great.
Thanks!

When to use double size images

I was thinking to write some quiz app where questions are represented as images.
My question is, for each quiz question (question.jpg), and thus a jpg file, do I have to create
a double sized question#2x.jpg file?
Is it necessary?
Doing this seems will increase size of my program so I was thinking when/if this is necessary to do?
PS. And in case I have to do it, I will just have to double in size each image manually and add to the project right (both original and double sized image)?
PPS. Just to add more info. The questions are located on the web site, I have to download them and add to my project manually (like resources). On web site there are no different versions of the same image. So, I have whatever is on the web site. Some images I noticed are 800x600 in dimensions but some are also in dimentions 500x400. So after I download these images, how shall I name them? Just with original names? and forget about the #2x extension? What's the best practice?
(if this will help my image view will probably be smth .like 310 in width). Do I have to modify them in size? What to do?
Apple's naming conventions of high resolution images can be found here:
Apple doc naming conventions
If you are developing in the way that you want to support old screen as well as retina screens. You can use xxxx.jpg for old devices as iPhone 3gs and iPad 1, and use xxxx#2x.jpg for retina displays. Where the aspect ratio needs to be the same but the #2x image needs to be twice as big.
In your case "my image view will probably be smth .like 310 in width", then the #2x image needs to be 620px in width and normal revolution 310px.
There is actually no need to have both image sizes in the app as you can use the same image and just scale it(If you really really need to have the old resolution supported).
Even if you add just a #2x, it will scale itself if someone on an old device installs your app. It may become a bit blurry but will still be quite ok.
If you are planning to use a lot of images in your app I suggest using some sort of web service where the user can download content that is to be shown. But that's just me. As the app will quite quickly become very large as images takes up quite a bit of space. Of course this all comes down to how many images you will have.
The drawback of using a web service is that the user much have an internet connection to be able to play. And download your content.(Most quiz apps I know of does use a web service for this.) This is a matter of taste.
If you do need to support normal and #2x here us a method you can use. This method will return the scaled image so you just need the normal one or the #2x one and then scale to the other size. This will at least help you a bit when it comes to getting either your app size down or your clients download time down.
If you are using .jpg's and scaling them upwards you can quite easily get a pixalated image as it is a lossy format. But if that's what you still want to do and maintain aspect ratio, this is one way to do it:
-(UIImage*)resizeImage: (UIImage *)imageToScale withScale:(CGFloat)theScale{
UIImage *image = [UIImage imageWithCGImage:[imageToScale CGImage]
scale:(imageToScale.scale * theScale)
orientation:(imageToScale.imageOrientation)];
return image;
}
Usage
[self resizeImage:[UIImage imageNamed:#"question.jpg"] withScale:0.5];
0.5 would double the size and 2.0 results in an image half the size as the original.
If you want a more complex method to set for instance set a specific target size just say so and I'll edit this answer.

UIImage resize performance and quality issue

I'm working with UIImage and like everyone else have to deal with retina and non-retina display adaptability. As for as I know, retina display requires double pixels.
I'm wondering if I could simply use a large image with the same width/height ratio, just resize it smaller to adapt all device?
For example, I made a original image with size of 200*200 pixel. Now I want to use it in application as 20*20 pixel, and 80*80 pixel (two situations). Then I have to make four copies like img2020.png, img2020#2x.png, img8080.png and img8080#2x.png
So if I want to use it in three situations with difference size, I have to store 6 copies. Can I just use UIImage's resize function to do this? I've tried a bit but cannot figure out it's quality and performance.
Any ideas? Thanks a lot :)
All native API suppose you to use image.png and image#2x.png, so it may be difficult sometimes to use just one image and scale it depending on retina/non-retina. Moreover using retina graphics on non-retina devices lead to more extensive use of these devices' resource causing battery drain. And, of course, if you have many images, that will decrease performance of your application. In other words there are reasons to use double set of images and you should better use it instead of one large image being scaled.
You don't need to make 6 copies. You should use the size 200*200 pixel. And set the property contentMode of imageview to aspectFit. Or you can also use below function and change the size of images at run time.
-(UIImage *)Resize_Image:(UIImage *)image requiredHeight:(float)requiredheight andWidth:(float)requiredwidth
{
float actualHeight = image.size.height;
float actualWidth = image.size.width;
if (actualWidth*requiredheight <actualHeight*requiredwidth)
{
actualWidth=requiredheight*(actualWidth/actualHeight);
actualHeight=requiredheight;
}
else
{
actualHeight=requiredwidth*(actualWidth/actualHeight); actualWidth=requiredwidth;
}
CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
I made some comparisons before. Leaving iOS handle the resizing causes lower quality, and really unacceptable sometimes.
I feel lazy sometimes, my approach is to run it with the retina version, and if it looks bad, I will create a low-res version.
If you're writing an iPhone-only app, most of iPhones on the market has retina, so I don't think you should worry about non-retina version. Just my opinion though.

Resize UIImage in Place

I have a category (very popular code found on web) to UIImage to do various image manipulation.
- (UIImage *)imageScaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext(newSize);
[self drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
One aspect that I am making heavy use of is scaling an image down. My app can take quite large images and scales them down to a "working" size. However, there are still times when the app crashes due to memory. This is because the category creates a new scaled image from the original. Therefore, the original HUGE image is still resident while the new smaller (but still big) image is created.
So, my question is, is there a way to load this large original image and rescale it in place? That is, rescale the original without creating a new image, and not allocing more memory?
Yes, and there is even a complete working Apple sample project that does this for you.
As far as I know there is no limitation on what size image it can scale down. Of course though, the larger the image the more time consuming the process is.

Resources