I am building an apparel catalog on the iPad. The app will contain over 2000 jpg product images at 2048 x 1536 # 72ppi, plus 2 sizes of thumbnails for each image. The large size of the primary images is to allow for zooming in on the products at reasonable resolution. The larger thumbnails will be displayed on each page to show alternate colors for each product. The smaller thumbnails are used in a side-scrolling pop-up filmstrip-style page browser.
I am dynamically resizing the larger thumbnails from the full-sized images as each page is displayed (in a paging UIScrollView). The smaller thumbnails are pre-rendered in photoShop to maximize the performance of the side-scrolling page browser.
Aside from the space taken up on the device from so many images, what other issues or concerns are there around the large number of images in an app like this? Memory management is under control because I am paging the large images in and out as needed as the user moves between pages in the main UIScrollView.
You are going to want to take a look at the PhotoScroller sample code. Those are mighty large images, and will cause your app to crash with the amount of memory they consume.
To page between pages, that means you'll have 2 images always loaded. If you can tile the images, I strongly suggest you do, that will further reduce your memory footprint.
Keep in mind that just because you can use say, 80 MB of memory for your application, does not mean you SHOULD use that much. Be a nice neighbour, your application will run along side other applications which themselves, use memory. Try and reduce your footprint however possible.
If you are dealing with the large image memory management properly (by tiling) and your customers are aware of the sizes of the app and/or downloads then there really isn't much other concerns.
The iPad has enough processing power to handle this kind of image processing pretty swiftly, but I wouldn't expect this to run great on an older iPhone.
To prevent crashing, I would quadruple check that your memory management works the way you say it does, and that you definitely don't ship with NSZombieEnabled on.
In my opinion, if you're dealing with that much data you should build a hybrid app, and host all the images on a web server somewhere. An image that size can approach 1 MB: 1MB * 2000 images = 2 gigabytes of storage space on the phone consumed.
Related
The images I am getting back from the photo library and camera are HUGE, and it takes a significant amount of time to send them over the network even in good conditions. I can't imagine a scenario in which I would need the full double-digit MB image, but maybe I'm missing something? Is it common practice to resize them before sending them over the network?
Yes it is common practice to alter an image's dimensions and compression so that it is appropriate for application.
As observed, by the default images from the camera are very large so that they can be displayed on large screens, printed to posters, zoomed and cropped etc without appearing unduly pixelated. So unless the app in question is a photo/image manipulating app, then resizing will almost certainly be beneficial in that it can improve networking, the app's memory foot-print and it's overall snappiness.
In terms of how to size and compress, while it is possible to store multiple versions of the image for each device that's being supported.
Practically, it seems that storing a single image at the dimensions required on the lowest resolution device but then only compressing it enough so that the higher resolution devices can scale up as needed without looking ugly seems to deliver reasonable results.
In terms of resizing, there are various posts on SO e.g. How do I resize the UIImage to reduce upload image size
I've also stuck gist for the UIImage extension I'm currently using to do this in my App over on GitHub here.
Have fun.
You can transform the image into data and then use this:
let imageData = image!.jpegData(compressionQuality: 0.5)!
It will make the quality less than usual with 50% to be able to save it quickly and smoothly
At present one of my quiz game require, many images of flowers based on questions asked.
I can say total 250+ images with resolution of 512x435 each.
Plus other games textures get loaded at a time.
So when game screen get opened which showing all these images, its on the spot get crashed.
I am testing this on iPhone devices. So how to handle these many textures? I was stuck in this point.
Here is overview of flowers textures.
I was displaying all these in grid view so in one scrollable screen all get displayed.
Now I hope, you understand my side point of view.
You need to reduce the amount of these images that are loaded at once, try keeping most of those images rendering components disabled using some sort of managing script when you are not seeing them, rather than simply putting them off camera and try to moderate the amount that are rendered at once. If this does not work the problem might be that the total size of the images is bigger then the amount of ram your device has. Even the IPhone X has only 3GB of ram, check if your images in total are bigger than or close to the 1GB-3GB range, unity remote 5 is probably storing these images in ram or temporary memory. It is always a good idea to try to compress your images when working with a mobile device anyway, try to put them into a texture atlas or lower the quality of them until the iphone can handle it, you should never rely on mobile devices to render tons of images at once.
Wow. That's a lot of flowers....
Okay if you need all of those textures, and you're only displaying them in the editor, I'd group them into folders.
Even if you sort the blue from the red..... etc just human readable directories it will help out a lot as you won't load ALL of your images at once.
If you are loading all of those textures at runtime, which I don't think you would as unity optimizes your built executable, I would recommend against loading all of the images at once because you will use a lot of RAM, especially if those images are 512px or larger.
With in the application you could split them into 25 at a time on the screen and you could swipe to the right to go to the next 25 or swipe back to the previous. This is how i solved a similar problem in unity a while back.
I am developing an iPhone app with skiing destinations being listed in an UITableView. The table view can contain up to 2000 cells. Every cell has a small weather icon of 25x25px (Retina 50x50). I am already using weather icons on the detail view of every destination. These icons are twice the size: 50x50px on the 3GS and 100x100px with Retina display.
As rendering pngs in a UITableView is pretty memory consuming I am not sure if I should use the larger images also for the table view or if I should design images half the size for the table view only. Of course this would increase the download size of the app by about 300 KB.
It would be nice if anybody could give me an advice if it is best to recycle larger images in the app or if it is best to design images for every resolution needed.
Thanks in advance
Martin
You definitely want to use 2 images. If you use 1 image, you are using more memory on non-retina screens, but the same on retina screens. Using 2 images uses the least memory. There should be no problem with memory whatsoever with what you are doing, so I'd venture to say that you are keeping the images in memory after they are needed, which is unrelated to the table view code.
A good thing about UITableView is that it's memory usage is not particularly related to the cell's sizes. The little hoops you have to jump through as the datasource are there so that the table can recycle cells, keeping the memory relatively fixed with respect to memory usage of a given cell.
Recycling cells trades speed for space, so there's a more legitimate concern about scroll performance. This is related to the setup effort per cell (since they are being recycled and re-setup all the time). Image size can be factor here, but I don't think so at the scales you're considering (50^2 or 100^2). This is the kind of thing best investigated by running on real hardware.
On binary size, I think you're correct that a single version of the images would reduce the app download. It's probably not a make or break factor at 300k, but kudos for considering it.
I have an app that will display a bunch of images in a slideshow. Those images will be part of the bundle, thus distributed with the app.
All the images are photographs or photographic, etc.
I've read that it's preferred to use PNG as the image format, but seeing that the JPG version will be much smaller, I'd rather be using that.
Are there any guidelines which format to use and in which case?
PNG's are pixel perfect (non-lossy), and require very little extra CPU energy to display. However, large PNGs may take longer to read from storage than more compressed image formats, and thus be slower to display.
JPG's are smaller to store, but lossy (amount depends on compression level), and to display them requires a much more complicated decoding algorithm. But the typical compression and image quality is usually quite sufficient for photos.
Use JPG's for photos and for anything large, and PNG's for anything small and/or designed to be displayed "pixel perfect" (e.g. small icons) or as a part of a composited transparent overlay, etc.
Apple optimizes PNG images that are included in your iPhone app bundle. In fact, the iPhone uses a special encoding in which the color bytes are optimized for the hardware. XCode handles this special encoding for you when you build your project. So, you do see additional benefits to using PNG's on an iPhone other than their size consideration. For this reason it is definitely recommended to use PNG's for any images that appear as part of the interface (in a table view, labels, etc).
As for displaying a full screen image such as a photograph you may still reap benefits with PNG's since they are non-lossy and the visual quality should be better than a JPG not to mention resource usage with decoding the image. You may need to decrease the quality of your JPG's in order to see a real benefit in file size but then you are displaying non-optimal images.
File size is certainly a factor but there are other considerations at play as well when choosing an image format.
There is one important thing to think about with PNGs. If a PNG is included in your Xcode build it will be optimized for iOS. This is called PNG crush. If your PNG is downloaded at run time it will not be crushed. Crushed PNGs run about the same as 100% JPGs. Lower quality JPGs run better than higher quality JPGs. So from a performance standpoint from fastest to slowest it would go low quality JPG, high quality JPG, PNG Crushed, PNG.
If you need to download PNGs you should consider crushing the PNGs on the server before the download.
http://www.cocoanetics.com/2011/10/avoiding-image-decompression-sickness/
The Cocoanetics blog published a nice iOS performance benchmark of JPGs at various quality levels, and PNGs, with and without crushing.
From his conclusion:
If you absolutely need an alpha channel or have to go with PNGs then
it is advisable to install the pngcrush tool on your web server and
have it process all your PNGs. In almost all other cases high quality
JPEGs combine smaller file sizes (i.e. faster transmission) with
faster compression and rendering.
It turns out that PNGs are great for small images that you would use
for UI elements, but they are not reasonable to use for any full
screen applications like catalogues or magazines. There you would want
to choose a compression quality between 60 and 80% depending on your
source material.
In terms of getting it all to display you will want to hang onto
UIImage instances from which you have drawn once because those have a
cached uncompressed version of the file in them. And where you don’t
the visual pause for a large image to appear on screen you will have
to force decompression for a couple of images in advance. But bear in
mind that these will take large amounts of RAM and if you are
overdoing it that might cause your app to be terminated. NSCache is a
great place to place frequently used images because this automatically
takes care of evicting the images when RAM becomes scarce.
It is unfortunate that we don’t have any way to know whether or not an
image still needs decompressing or not. Also an image might have
evicted the uncompressed version without informing us as to this
effect. That might be a good Radar to raise at Apple’s bug reporting
site. But fortunately accessing the image as shown above takes no time
if the image is already decompressed. So you could just do that not
only “just in time” but also “just in case”.
Just thought I'd share a bit of decompression performance data...
I'm doing some prototyping of a 360 degree viewer - a carousel where the user can spin through a series of photos taken from different angles, to give the impression of being able to smoothly rotate an object.
I have loaded the image data into an array of NSData's to take file i/o out of the equation, but create NSImage's on the fly. Testing at near max frame rate (~25 fps) and watching in Instruments I see the app is clearly CPU-bound and there's an approximately 10% increase in CPU load showing ~275 kb png's vs. ~75 kb jpg's.
I can't say for sure but my guess is the CPU limit is just from general program execution and moving all the data around in memory, but that image decompression is done on the GPU. Either way and the JPG vs. PNG performance argument looks to favour JPG, especially when the smaller file sizes (and therefore smaller sizes of objects in memory at least in some parts of the chain) is taken into consideration.
Of course every situation is different, there's no substitute for testing...
I have found massive differences in animation performance when using jpegs vs png. For example placing three screen-sized jpegs side by side in a UIScrollView and scrolling horizontally on an iPhone4 results in lag and a thoroughly unpleasant jerky animation. With non-transparent pngs of the same dimensions the scrolling is smooth. I never use jpegs, even if the image is large.
I think if you want to use transparent, you have no choice except PNG. But, if your background is opaque already, then you may use JPG. That is the only difference I can see
'Use JPEG for photos' as mentioned in Human Interface Guidelines under section Produce artwork in the appropriate format.
So I've seen this question asked before and in fact I asked it last night but I thought I'd give it another go just to see if I could get any other unique views on the problem.
The Problem — I have an app with a large number of uiimageviews (with image downloaded to disk) in a scrollview which of course has two large problems facing it: Memory use, and performance. In my app memory use isn't so much a problem because I am employing techniques such as dequeuing and reusing imageviews and such. But performance is another thing entirely. Right now, as a memory saving procedure, I only store image filepaths in memory because it would be ridiculous to store images in memory. But the problem with this is that reading from the disk takes more time than from memory and slows down scrolling on the scrollview immensely.
So, what kind of techniques do any of you suggest for something like this? I've seen three20 but don't want to use it because I need high customizability in my view and that just won't do. Image files are not large, but just thumbnail size so there is no scaling or excess size. There's got to be an intuitive way to handle this. The built in photos app handles up to thousands of photos perfectly with low memory and slick and smooth scrolling performance.
Fundamentally, the problem is that you're probably doing a bunch of disk I/O on your UI thread, which is basically guaranteed to cause performance problems.
You should consider loading your images on a background thread and updating the image views on the main thread when the images are loaded. Depending on your use case you can get more or less clever about how far you preload in advance, etc, so you can have images ready. (There might be some usable source code or even Apple sample code out there that does something like this, but I don't know of it off the top of my head.)
You may notice that some applications (not sure about the Photos app) have an intermediate stage where they load a very small thumb size image for all images, and scale it up to the render size, which acts as a placeholder until the full size version is loaded-- if the user scrolls past that image before the full size is loaded, the visible effect is nearly the same as if the image was there all along.