I have an app which display images in full Screen. Some of the images are 1952x3680 pixels and these images are raising memory warning level=1 and level=2.
How should i handle these image?
Scale your images down considerably. There is absolutely no reason you need images at that resolution in an iPhone app.
Don't use them. Either get your server to deliver a thumbnail version of the image (maybe using a thumb.php/jsp/asp/... file with GET params x=<width>&y=<height>), or scale the image down on the iPhone and discard the original data. The former method is vastly preferred as it saves on both bandwidth and large memory allocations client-side.
The largest images you should be working with are 480x320 (iPhone 3GS and earlier) and 960x640 (iPhone 4).
EDIT: The other situation I didn't think of is if you're bundling these images with the app. Please, please don't do that. If you have images that big, scale them down in Apple's Preview or any image editor to the sizes noted, and ideally have two copies, image.png and image#2x.png which are shown depending on the scale of the device's screen.
The screen itself is only 320x460 (not considering the clock bar on top), and 640x960 for retina display. There is no reason to have images this large to begin with. Scale them down. It'll both prevent the memory warnings and stymie unnecessary image size.
As said before, scale it down if you only want to show the image without zooming in fullscreen.
If you need to zoom and show it detailed, google for CATiledLayer. There are good examples around.
Related
I am trying to reduce the size (30+ MB) of my binary submission, and I sense that images acquire a sizable (>26 MB) part.
I also observed that if I remove retina images (#2x.png), iOS gracefully replaces them with 4-inch retina (-568h#2x.png) versions.
Are the retina images really redundant if I supply -568h#2x.png versions?
P.S.
Not that one image makes much of a difference, but if the answer is a Yes, does this also apply for default.png?
#2x images are for retina devices. They look much crisper and clean on retina devices (e.g. iPad3, iPhone 5) as compared to their non-retina counterpart images. Here are few suggestions to reduce size of your binary.
1) For background images check if they are really needed. If they are simple solid color images you can simply set the backgroundColor of the UIView.
2) Whenever possible use 9 patch (also called 9 scale) images for button or view backgrounds. They are generally 1 px wide images and you can use below method of UIImage to use them
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode
In general image#2x can be used as a stand in for image, but not the other way around (because they wouldn't look good). The side effect of doing this is that more memory will be used and on non-retina devices that could cause a problem. If you aren't supporting non-retina devices then you don't need any images.
Generally speaking you shouldn't have many image-568h#2x images other than the Default and other background images. Most of your content images will be the same size no matter what the screen size is. You do not need differently named images for a button of the same size on multiple different screen sizes.
I have a multiplatform iOS/Android game that I programmed in Cocos2d-x. I have only one set of images to use (I'm only after high res devices) that get scaled according to the device's resolution. For example all images are for the iPad but if you are using a Galaxy S then the image locations and scaling are affected by GalaxyS_screenWidth/iPadscreenWidth.
This works fine for all Android devices and on iPad, iPad2 and old iPhones, but with Retina iPhone there is a problem. On the iPhone 4 all my images look extremely pixelated, a result from the images being scaled to iPhone non-retina resolution then scaled back up to fill the screen.
I tried enabling Retina Mode and the images are half of their intended size (maybe due to the usage of get winsize() which uses points) and scaling manually causes other sorts of problems. I tried playing with a lot of options and attributes but to no avail, so what should I do now?
EDIT:
This is not only a graphics issue, as text gets automatically scaled down then up and appears pixelated.
EDIT 2:
Fonts are bitmaps so my bad. But I don't want to use retina as all images are already retina by default. All of my images are set up for the iPad so for iPhone 4 I just scale them down a bit. This works with Android phones.
For example I have an image, depending on screen resolution obtained through getwinsize():
If current resolution width is 1024 then image stays the same.
If current resolution width is 900 then image gets scaled by 900/1024, no problem.
If device is iPhone 4 resolution width is 480, so image gets scaled by 480/1024, then cocos2d-x automatically scales the resulting image by 2 thus the pixelation. I tried using getwinsizeinpixels, I tried multiplying the screen size, I tried many things but nothing worked out of the box unless I am to redo many of my code.
So the question is, how can I just let the damn engine treat the iPhone 4 as an Android phone with resolution of 960x640?
If you want Retina resolution images to look like Retina resolution images, then those images need to be in Retina resolution (960x480).
If you first scale down the image to 480x320 and then upscale it on the device, it will of course look blurred. You can't magically make the Retina pixels appear from a lower resolution image by scaling it up.
SI couldn't get to the bottom of it so I employed a hack. I enabled Retina Display then I scaled everything x2 through code except for the text. Sounds stupid, but it worked, and pixelation is gone. Thanks everyone who spent time trying to help me.
I tried enabling Retina Mode and the images are half of their intended size
when you enable retina support, cocos2d gets images by appending #"-hd" to their provided filenames. Such images are meant to be double the "visual" size (in iOS terms, pixels vs. points), so that they can be sort of scaled down to make full use of device resolution.
If you have a look at the CCDirectorIOS class, you will find there a couple of methods dealing with this, especially those dealing with the scalingFactor. I don't know what kind of changes you should do to make it work, but if you step into those methods and look at the value of various objects, you might find a way to modify cocos2D default behavior for your specific case.
If this seems to complicated, one thing you could try is changing the CC_RETINA_DISPLAY_FILENAME_SUFFIX so that cocos2d will not look for specially-named files for the retina iPhone, but just use the normal ones.
For example all images are for the iPad but if you are using a Galaxy S then the image locations and scaling are affected by GalaxyS_screenWidth/iPadscreenWidth.
Another thing you might try is not using winSize, but winSizeInPixels, so that when you scale down, you down do it down to the point resolution, but just to the pixel resolution (which is double the point resolution).
Hope this helps.
I'm wondering what will happen on a non-retina display device if only the #2x image is copied to the resources? Will it scale down the retina display image by 0.5 to accommodate the frame of the UIImageView?
I hope this isn't a silly question!
The high resolution #2x images are not automatically down-sampled on non-retina devices.
Apple did not implement such feature because non-retina devices generally don't have enough memory to load and down-sample many high resolution images during initialization, it might cause trouble in case too many images need to be initialized.
EDIT (Based on answer by WendiKidd)
Non-retina devices will however down-size and display the high resolution #2x images, but without down-samling them, which causes poor image quality.
I know for a fact that it will use the #2x images if no regular image is available, because I have tested it myself. (Though I agree with David's comment--this is rather easy to test yourself.) Now the image quality is decreased, because it's trying to resize an image that is much larger than the space you're trying to put it in. But it absolutely will work. Go give it a try and you'll see :)
I am currently working on an image gallery for iPad. As of now there are about 100 images and the count may increase further. The images I am using are of the resolution 2134x1602 # 300dpi. Now with ~2.5MB, i have lost the smoothness in scrolling the images to next image. Also I want to zoom the image up to 8X. The images I am using are all PNG type.
The app works fine in the simulator but crashes bad on the device. Instruments show no leaks and no bad allocations too. It must be some Internal memory issue for sure since the gdb reports memory warning while running on the device. I would like to tell you that I am lazily loading the images.
Can anyone help me with this issue and the strategy i should use to get rid of the slow loading and scrolling. Also I'll be glad if you let me know how an iPad's GPU processes the images it wants to load. Also i would like to cite that changing DPI didn't work out well.
Eagerly waiting for some help.
Thank You.
Your app is crashing because you are running out of memory.
What you will need to do is scale/tile the images. Have a look at how Google Maps works in a web browser on a normal PC, you will need to do something like this. The screen resolution on the iPad is 1024x768 pixels, so there's no point loading more than that amount of data at any one time. When displaying your image at > 0.5x scale, tile it into sections that are max 1024x1024, pre-scaled. Cache everything to disk. When displaying your image at < 0.5x scale, consider having thumbnails at different resolutions. In between different resolutions, do an alpha blend of two images of different scales: eg for scale 0.75x, do a 50% blend of four tiled scale 0.5x images and one scale 1.0x image.
I have built a photo app for the iphone which has albums of high resolution images that the user can flick through. It's based on Three20 and the TTThumbsViewController.
The images are currently mostly 2048x2048 or thereabouts but this seems too large given the screen is only 1024x768.
Is there any value in leaving them at the higher resolution or should I drop them to 1024x768?
If you want to allow some kind of zoom/pan functionality, then there is value leaving them at a higher resolution. Otherwise there isn't: they take up more space and need to be scaled down anyway.
Just a note: scaling up or down by a couple of pixels is bad for sharp edges. Try to avoid this.