How to store a very large image on an iPhone/iPad - iphone

What's the best way to store a very large image for an iOS app? I want an app to be able to view images that might be hundreds of megabytes, perhaps as much as a gigabyte as jpeg. I need to be able to store the image and retrieve selected areas for display.
Currently the images are cut into 512x512 pixel tiles and stored as jpeg files in a directory tree with tens of thousands of tiles (actually an image pyramid including downsamples).
Ignoring the question of displaying the image, I'm interested in the most efficient, manageable way to store this data on the device: files, like they currently are, in an sqlite database or something else?
Second part to the question. Is there a limit to the amount of data an app can store, or can an app keep importing data up to the storage limit of the device. I'm asking here about data that an app imports after it's installed.

The solution to this is to pre tile the enormous image so the tiles can be quickly retrieved from the file system on an as needed basis. One problem with very large images is that most solutions require the whole image to be rendered into a context, consuming vast amounts of memory. On a system like iOS, where memory is limited, the way to solve this is to use a library like libjeg or libjpegturbo to render an image a line at a time, then save the pixels into a raw file. The downside to doing this directly is that when you need one tile, you need to jump all over the file system finding each row of a tile. Thus a better solution is to not only incrementally scan, but incrementally tile too. You can use mmap to map the file into just the area you need, so you can really minimize memory consumption. That said, you can thrash the Unified Buffer Queue on iOS so badly the app crashes, or even the whole system!
If you are curious about how to implement the above solution, there is a freely available project on github - PhotoScrollerNetwork - that does all the above.

A sample from Apple: PhotoScroller

What about splitting into parts. Then it can be gathered by your application if needed

Related

Is it a good idea to store pictures / images in SQLite DB from the App?

Some discussions in Stackoverflow say that storing the picture in DB is a bad idea (a because overtime, the number of images get large & may lead to app crash). So, either
a. the image can be stored in the iPhone itself & only its location can be stored in the DB
Potential Issue: The image might get removed (outside of the app) & the app might not be able to load them the next time
b. the image can be shrunk to a small size (say, 100*100 pixels) and stored in the DB
Potential Issue: will size be an issue if the image is shrunk to just 100x100pixels?
c. Doing both (a) & (b). So, small versions of the images will be stored in the DB and then, retrieved & displayed in the App, whereas, if the user chooses to see the original version of the image (whose probability is low), then that'll be fetched from the local directory & shown.
Your suggestions please? In my opinion, (c) seems a good option to go in for, in case (a) has the potential issue mentioned.
It really depends on where the images are coming from. Are they being downloaded from the Internet (or imported from the user's library / camera) after the user installs the app, or are they bundled with the app from the App Store?
If the images are being downloaded / imported, the best solution is to store images in the filesystem following the recommendations in http://developer.apple.com/library/ios/#qa/qa1719/_index.html
Basically, if the images cannot be replaced or recreated, store them in the <Application_Home>/Documents directory and do not set the Do Not Backup attribute. These items will be backed up to iCloud, and this data does persist for at least some amount of time even if the app is deleted from the device. (Remember that your users do not have unlimited iCloud space. Be responsible.)
-However-
If the images are bundled with the app, the best solution is to import them directly into your Xcode project and reference them from there. This way you know they are always available even if the user deletes and reinstalls the app.
I would definitely stay away from storing image data in the databased whenever possible. There are simply better, more efficient ways in most any scenario.

Downloading large amount of images, making it faster

I need help with downloading from webserver...
What i currently do is get XML file from web servers that contains image locations, parse XML, download each image, store image on iphone, and store image name to sql database.
This takes lots of time because there is large amount of images to be downloaded and i am downloading one by one.
My app update just got rejected because reviewer decieded that downloading is too long... What is funny, last two updates passed without problems..
I was thinking about zipping those images on server and sending zip file to iphone, unzipping it there, or packing images together with binary and sending it to apple.
Any advice on how to make download faster, would be appreciated. Thanks.
BTW, zip won't help with images. They are already compressed, so it will just add overhead. Make sure your images are not any larger than you need for display and I'd do what Mario suggested above and download them in multiple async calls (at least make the one big call asynchronous.)
A key principle of UI design is to display partial results (unless they are invalid or misleading) so that the user understands that progress is being made.
If you really need all the images to make it valid, you can download a few and display them grayed out (alpha = 0.4) or something so that it's clear that this is a partial result, but that progress is being made. The reviewer probably felt that it was taking too long to startup.
Do you change those images often? Or only once per release if at all? If they change with each release only I'd package them. If they're almost never changed, go with the one huge download (so people don't have to redownload when updating) and if they're change often, download them file by file but try to do 2-3 files at once using asynchronous download (if supported).
1) I would use something like an NSOperationQueue to download around three images at a time in the background. Much more than that and the UI starts getting choppy.
2) Also display some kind of loading indicator while this is going on.
3) What format are your images in? If you are transferring over the network you should use JPG, and consider setting the quality level to something smaller (say 6 even 5). To offset the loss of quality you could send down larger images, even with the larger number of pixels you can easily be better off with a lower quality compression.
4) If you have to use PNG to preserve transparency, consider using PNGCrush on the images before sending. As noted, zip will do pretty much nothing.
One way to speed up download of those images is to put them on a CDN. Some CDNs, like Limelight have special network optimizations for sending data to mobile devices. They also just do a better job of routing content, and have higher capacity for transmitting content. What's nice about this approach is that you might not have to change your app. However CDNs can be pricy.
Likely, your images are just way too large. You said you're worried about the 20MB app limit, but I think at that point, your images are just way too large for the phone.
Rather than zipping the files, I'm pretty sure you need to downsample the size of the images. Not only that, but you should only download the ones that you need, when you need them.
If you still want to have bulk downloads, why not have it as a side option rather than the default implementation?

storing an jpg image from internet to disk / db

I don't know which is the most efficient way of organizing images downloaded from server. I will be downloading around 200 images on to my iPhone on request for download. Which is the most efficient way of organizing ? just dropping it as a file on the phone's memory or having it in sqlite (via coredata) after download ? which one is most efficient and easy to handle ? which access is faster ?
The rule of thumb is to put them (or any bigger binary data) onto disk directly, and if the whole app organizes its data with a database / CoreData, then put the paths of the images in there.
AFAIK , Iphone has minimum 8GB of memory. That will be enough for images. Also It depends upon the frequency of image downloads. If you download 200images daily then u need some application that will push it in your sqlite db. Advantage of this will be your all image files will be inside a single db. No scattered images. But if you want to store only 200 images then i would recommend it store on your phone memory with some image managing tool like ACDSEE in windows, that will help you viewing images in slide show or what ever manner you want.

how to decrease the application size

My problem is that my application size is very high,
is there any idea to reduce size of application?
if i make application without content and content is uploaded my server then how i sync the application with content put on my server?
i want to know that once user download application after that when he use application then we stream the content and save his document folder.
once user stream then never required for streaming.
is it possible????
Thanks,
Reducing the size of your application depends on the TYPE of contents of your application. I highly doubt that the application code is the cause, and since you did not mention what they are I am assuming they are some kind of resource.
If your resources are images, try to use image compression programs. Or convert them to smaller sized images or optimize the images.
If your resources are documents / text files / files that have a high compression ratio when zipped. Then you can try to zip your resources and access them inside the compressed file (this will mean additional coding, and probably slower in performance).
These are just examples.
It is not advisable to stream large contents because it uses the network bandwidth which, depending on the user's plan, can cause a big spike in phone bills.
Yes it is possible that you can download your content and can save to application's document folder, when user runs your application for the first time. Thought it may affect the first impression to your user as it will take time to download.

iphone best way to store images

I'm developing an app that needs to cache some images from the web the images are likely to be 100x100
I just need to know which is better:
Store the images as files in the iPhone file system
Store them as blob in a sqlite Db along with other data already saved on the database.
Appreciate your help.
Storing images in the database is definitely not recommended by Apple, the filesystem is actually really good at locating files (images in this case) on the disk, which makes it the best solution for saving images. These were the exact same words an Apple technology evangelist used in the iPhone Tech Talk World Tour in Paris. If it are only a few images, you might get away with it, but when the number can potentially become quite large, files is the way to go.
Besides, you can use the lazy loading methods to grab the images of the disk, this will delay loading the image from disk to when it really is needed.
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image.png"]]
Edit: imageWithContentsOfFile does not load the image at once, thus not locking the thread, neither does it cache the image. The other method imageNamed: does lock the thread and loads the image at once, on the bright side, it does cache the image.
From past experience, storing (and retrieving) images from the file system should be a bit faster than from the DB. As for ease of handling and maintenance it only depends on what you're more familiar with: SQL scripts or iphoneOS file system functions.