How to Store Large size Images into iPhone Application?
Images are taken from UIImagePickerController but saving into Database and retrieving from
Database crash the application.
If your images are large enough, then you should NOT store them inside Sqlite. Instead, you should simply store in the database the pathname where you actually save the image in the filesystem (say for example the Documents directory of your application).
Now, it is up to you to decide what is large enough. To me, binary data greater than 1 megabyte is large enough to decide not to store the data inside the database. The threshold is dictaed by practical consideration related to the speed of both Sqlite and the filesystem.
Related
Whats the most effective way of dealing with different image resolutions in Parse for the different ios devices?
For instance
Would it be better to have 1 image in parse at the highest res and download for every device? (slower download speeds for lower res devices)
Have 1x 2x and 3x versions of the image in Parse and download for relevant device. (takes up more storage space on Parse)
Run cloud code on Parse to resize the images to their correct resolution as they are downloaded to the devices. (possible slower download speed for all devices?)
Any other options anyone can think of would be welcome.
Al
I would say this strongly depends on the usage case. For example, if you have a profile picture, I would recommend uploading it in 2-3 versions, as those pictures may be downloaded very often (for example in a social networking app where you have profile pictures in posts, user profiles, messages, etc.). When the picture is downloaded a high amount of times, you would rather download a smaller one to minimise download time and save parse data transfer resources.
On the other hand, for pictures that aren't downloaded as often as other ones, I'd recommend storing them in a high-res format, and scaling them down (if necessary) as they are downloaded. Take for example again a social networking app. A post contains a profile picture (which is downloaded quite often) and the actual post (a photo in this case). The actual post photo is only downloaded a single time (ideally), so there should be no reason to worry about the download speed.
Basically (and that's the way I handle this), you should always try to cache every image. Images that can be cached easily and don't have to be retrieved very often can be stored in a single high-res format (saving data space on parse). Images that cannot be cached easily or have to be refreshed quite often, should be stored in different sizes, which will, in the end, save you data transfer. The small amount of extra storage does not have that much impact, to be honest, especially if you store them in scaled down sizes.
This is a rather simple question, but I haven't been able to pinpoint a clear answer in my searching.
If I have an NSArray, and add fifty 1MB UIImages to it, where does that 50MB get deducted from? Will the app be using 50MB more memory? Will it simply store it on the disk?
The same goes for Core Data where instead of using a persistent store I store it in memory. Would the size of the Core Data store take up exactly that much memory/RAM or would it live on the disk and be wiped when the app finishes executing?
I'm concerned whether or not I should be storing several dozen megabytes in UIImages in an NSArray, or if I should be using NSCache (I'd rather not as I'd prefer to never lose any of the images).
If I have an NSArray, and add fifty 1MB UIImages to it, where does
that 50MB get deducted from? Will the app be using 50MB more memory?
Yes.
Will it simply store it on the disk?
No. Arrays are stored in memory.
The same goes for Core Data where instead of using a persistent store
I store it in memory. Would the size of the Core Data store take up
exactly that much memory/RAM or would it live on the disk and be wiped
when the app finishes executing?
Yes, if you tell Core Data to story everything in memory, that's exactly what it'll do.
The line between "memory" and "disk" can get a little fuzzy if you consider that virtual memory systems can swap pages of real memory out to disk and read them back when they're needed. That's not an issue for iOS, however, as iOS doesn't provide a VM backing store and writeable memory is never swapped out.
I'm concerned whether or not I should be storing several dozen
megabytes in UIImages in an NSArray, or if I should be using NSCache
Those aren't your only options, of course. You could store the images in files and read them in as needed. You should be thoughtful about the way your app uses both memory and disk space, of course, but you also need to consider network use, battery use, and performance. Storing data on disk is often preferable to downloading it again because downloading takes time, may impact the user's data plan, and uses a lot more energy than just reading data from secondary storage.
I'm currently working on a concept for a new iPhone app, the would involve some very basic profile system.
Since all the other data will be stored in iCloud, I was wondering if it would be possible to store pictures in the cloud too.
I see that the storage per app is only 1MB, so this seems extremely low to store pictures.
The 1 MB limit is for Key-Value storage only (and KV storage is inappropriate for images for other reasons, too). If you use the Documents in the Cloud APIs, your app can store a large number of large files, limited only by how much space the user has (or hasn't) paid for. (Though it's wise to use that space judiciously and efficiently, as your potential customers won't be happy if your app alone causes them to blow the storage limits on their account.)
Now, I am developing a news reader app like BBC news iOS.
see in BBC News
In my app, I must download image from server to and show it in view to make users easier to choose the news they want to read.
For more performance, I must cache image to avoid reloading image for server.
I know that there are 2 kinds of cache: In-memory cache that saving images in memory (RAM) and DiskCach that save images in Disk to load it when we need.
My question is:
What is best images cache mixed strategies for my App? (use both in-memory cache and image-cache)
My solution is:
download image --> save them in diskcache + save them in memory cache --> load image from in-memory cache on demand and show in view ---> in-memory cache over its MAX_SIZE --> free in-memory cache ---> load image from disk cache on demand and save it to memory cache --> repeat........
Is my solution is right approach?
Another question: when in-memory cache over its MAX_SIZE --> we will free its --> all images in cache will lose so image in our view will disappear.
--> How to solve this problem?
Sorry for poor English.
Thank in advance.
In one of my projects I implemented pretty much the same caching methods (Disk Cache and Memory Cache).
Maximum cache size
Each cache system had its own max size limit. The "size" of each image was computed differently in the cache systems.
For the memory cache, each image would have a size computed as
image size = image width * image height (in pixels)
So, the maximum size for the memory cache would represent a the maximum area of a pixel surface
For the disk cache, I used the actual file size for each file.
Making room
When using the cache systems, you might get to a situation where one of the caches is full and you want to insert a new item in it - you have to remove some items to make room.
What I did was assign a timestamp to each entry in the cache. Every time I access that item I updated the timestamp. When you want to make room, you just need to start removing items from the oldest to the newest based on the last access timestamp.
This is a simple algorithm for freeing up space and in some cases might actually behave poorly. It is up to you to experiment and see if you need something more advanced than this.
For example, you could improve this method by adding a priority value for each item and keep old items in the cache if their priority is high.
Again, it depends on your app's needs.
Expiration
For the disk cache, I would definitely add an expiration date for each entry. If the memory cache is destroyed when the user completely terminates the app, images in the disk cache might be stuck in there forever.
Encapsulation
Another aspect I would consider, is making the caching system as transparent as possible to the programmer. If you want to enable/disable one of the cache it would be best to have most of the code remain the same.
In my app, I built a central content delivery system and I would always request images from the internet through this object. The caching system would then check the local caches (memory / disk) and either return me the image immediately or make a request to download it.
Either way... I, as the "user" of the caching system did not care what was happening behind the curtains. All I knew is I made a request to get an image from an URL and I got it (faster or slower depending if the image was cached).
I have a question on using the AssetLibrary with iOS. It it possible to store a pointer to an image in your app rather than the actual image? Let's say I want to create a playlist, but I don't want to store the actual image.
The reason I am asking, is that I find when I use the image picker, I can save an image to the devices documents directory, but once I get to 25 or so, it starts to slow down the device (iPad 1). I scale down the images if they are very large, I ran through the leaks instrument many times, and there are no leaks. I am just at a loss as to where to turn next, so I wanted to investigate alternatives. As I see nowhere where I can free up memory.
That's where I am at now, I'm curious if the AssetLibrary might be a option since I won't be storing physical images. I know it has some dis-advantages (requires users location, can be a bit slow when looping through images)
Any thoughts on this would be greatly appreciated.
Storing 25 images to the documents directory shouldn't slow down the device, unless you're trying to load all 25 extremely large images into memory at the same time.
You can't permanently store a pointer to the assets library asset, but you can store the URL you retrieve from the ALAssetRepresentation's url property and then use ALAssetsLibrary's assetForURL:resultBlock:failureBlock: to get back the corresponding ALAsset later. Do note that it is possible for the user to delete the asset from outside your program, even when your app is in the background, so if you are hanging on to an ALAsset you must listen for ALAssetsLibraryChangedNotification to know when to reload the assets.