Is it better to have a PNG, say 320px x 44px and display it once, or to have a PNG that is 320px x 4px and use [UIColor colorWithPatternImage:]?
I know that the iPhone handles PNGs well and decompresses them, so in terms of memory, would it be best to use the smallest possible images, and in this case, use the UIColor method to repeat it?
Are there any drawbacks to using colorWithPatternImage? Perhaps over larger areas, maybe half a screen size or full screen sized?
Many thanks,
Michael
I'm willing to bet that choosing one over the other won't make a noticeable difference in your app's responsiveness. The only place people might notice a difference is if they're downloading your app over EDGE, in which case the tiled image is the way to go.
I would do whatever makes your app most maintainable.
The answer depends on what "better" means to you. If you're more concerned about the size of the app, then smaller pictures would help you. If the application's speed is more of an issue than size, then a larger image will eliminate the need for all the colorWithPatternImage calls and effectively run faster.
Related
My dilemma -
I have a universal app that holds a lot of images and icon (about 1,000).
In many cases i use the #2x version as is for the iPad version, in other cases it is to big even for the iPad.
I see 2 options:
Add a unique images for the ipad (large the app size).
Scale the images every time i use them?
Would like to hear notes or ideas.
Thanks
Shani
I think you will here different suggestions here. It really depends on your requirements and whether it is more important (mandatory?) for you to reduce the size of your app or make it more responsive at run-time.
Are you going to scale the images down one-by-one (meaning that in a view you will have only an image)? Or are you going to scale down a whole lot of images to display, e.g., in a table view? This will impact greatly the user experience...
As to the "every time", you could think about using a cache, so that you only resize each image just once. This would be like an intermediate solution, but again, it depends on your app (if very many images will be loaded, the cache will become very large, so in this case it could be suggested to go for option 1).
Also, the iPad 2 is pretty fast; iPad 1 a little less, so you could also take into account that.
In general, I don't think that scaling down will add much overhead, but YMMV...
Saving images to a given location
i followed the above link and it works but i dont get actual image size...it is much bigger...
how can i fix it...
Thanks for any help
How do you mean - bigger?
The screen is 320x480 pixels. So if you the view you're saving is the whole screen, that's what you'll get.
Depending on your (computer) screen resolution, this may look quite big or quite small, and will almost certainly look different than the actual size of the iphone screen.
According to Apple, the iPhone 4 has a new and better screen resolution:
3.5-inch (diagonal) widescreen Multi-Touch display
960-by-640-pixel resolution at 326 ppi
This little detail affects our apps in a heavy way. Most of the demo apps on the net have one thing in common: They position views in the believe that the screen has a fixed size of 320 x 480 pixels. So what most (if not all) developers do is: they designed everything in such a way, that a touchable area is (for example) 50 x 50 pixels big. Just enough to tap it. Things have been positioned relative to the upper left, to reach a specific position on screen - let's say the center, or somewhere at the bottom.
When we develop high-resolution apps, they probably won't work on older devices. And if they do, they would suffer a lot from 4-times the size of any image, having to scale them down in memory.
According to Supporting High-Resolution Screens In Views, from the Apple docs:
On devices with high-resolution screens, the imageNamed:,
imageWithContentsOfFile:, and
initWithContentsOfFile: methods
automatically looks for a version of
the requested image with the #2x
modifier in its name. It if finds one,
it loads that image instead. If you do
not provide a high-resolution version
of a given image, the image object
still loads a standard-resolution
image (if one exists) and scales it
during drawing.
When it loads an image, a UIImage object automatically sets the size and
scale properties to appropriate values
based on the suffix of the image file.
For standard resolution images, it
sets the scale property to 1.0 and
sets the size of the image to the
image’s pixel dimensions. For images
with the #2x suffix in the filename,
it sets the scale property to 2.0 and
halves the width and height values to
compensate for the scale factor. These
halved values correlate correctly to
the point-based dimensions you need to
use in the logical coordinate space to
render the image.
This is purely speculation, but if the resolution really is 960 x 640 - that's exactly twice as high a resolution as the current version. It would be trivially simple for the iPhone to check the apps build target and detect a legacy version of the app and simply scale it by 2. You'd never notice the difference.
Engadget's reporting of the keynote included the following transcript from Steve Jobs
...It makes it so your apps run
automatically on this, but it renders
your text and controls in the higher
resolution. Your apps look even
better, but if you do a little bit of
work, then they will look stunning. So
we suggest that you do that
So I infer from that, if you use existing APIs your app will get scaled up. If you take advantage of new iOS4 APIs, you can get all groovy with the new pixels.
It sounds like the display will be ok but I'm concerned about the logic in my game. Will touchesBegan positions return points in the new resolution? The screen bounds will be different, these types of things could potentially be problems for me.
Scaling to a double resolution for display purpose is straight forward, but will this scalling apply to all api's that input/output a screen coordinate? If not things are going to break aren't they?
Fair enough if it's been handled extensively throughout the framework.. I would imagine there are a lot of potential api's this effects.
For people who are coming to this thread looking for a solution to a mobile web interface, check out this post on the Webkit blog: http://webkit.org/blog/55/high-dpi-web-sites/
It seems that Webkit has solved this problem four years ago.
Yes it is true.
According to WWDC it appears that apple has build it some form of automatic conversion so that the resolution for applications will not be completely off. Think up-convert for dvd to HDTV's.
My guess would be that apple knows what most of the standards developers have been using and will already be using these for an immediate conversion. Of course if you are programming an application to take advantage of the new resolution it will look much nicer than whatever the result of apples auto-conversion is.
All of your labels and system buttons will be at 326dpi but your images will still be pixel doubled until you add the hi-res resources. I am currently updating my apps. If you build and run on the iPhone 4 sim then it is presented at 50%, go to Window > Scale > 100% to see the real difference! Labels are smooth, my images look shocking!
When creating an UIImage file from a .png to be displayed on a button, view/cell background, etc. for a standard Iphone application, should all of them be in powers of 2 for optimization reasons?
As others have said, no - but you should generally use images with even dimensions. This is because when views are positioned with the center property, it'll position an odd-dimensioned image at some half-pixel position. This will cause the image to appear blurry.
As long as you're aware of this it shouldn't really cause you any problems, but it's still a good idea to use even sizes just to be on the safe side.
(This applies for UIKit, not necessarily OpenGL)
Apple uses odd and arbitrary dimensions for all the images it adds to the interface on your behalf, such as system toolbar items. The best optimization you can do is anything that reduces compositing, which basically means setting the opaque property of views and layers whenever possible.
If you have the choice between a transparent png that will be composited over a static background and an opaque png with the background already included, you have a chance to optimize. When the images will be sliding around or the background will change, you have to composite, otherwise choose opaque.
Here is an article on optimization of iPhone images -- basically tells you why to use PNG files. The size shouldn't matter unless you are using OpenGLES.
No, this will have little or no benefit, I usually suffice at doing my own optimization using photoshop "Save for web or devices" option.
Please see http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html for a detailed explanation about the iPhones pre-optimization of pngs.
When a PNG is added to an XCode iPhone project, the compiler optimizes it using pngcrush. Once on the device, the image's rendering performance is very fast.
My problem is that my application downloads its PNGs from an external source at runtime (from Picasa Web albums, using the Google Data APIs). Unfortunately, these images' performance is quite bad. When I do custom rendering on top of the image, it seems 100x slower than its internally stored counterparts. I strongly suspect this is because the downloaded images haven't been optimized.
Does anyone know how I can optimize an externally downloaded PNG at runtime on the iPhone? I'm hoping for a class that does this. I even considered adding pngcrush's source code to my app, which seems drastic. I haven't been able to find an decent answer myself. I'd be very grateful for any help.
Thanks!
Update:
Some folks have suggested that it may be due to the file's size, but it isn't. During my tests, I added a toggle button to switch between using the embedded version and the downloaded version of exactly the same PNG. The only difference is that the embedded one was optimized by 'pngcrush' during compilation. This does some byte-swapping (from RGBA to BRGA) and pre-multiplication of alpha. (http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html)
Also, the performance I'm referring to isn't the downloading, but the rendering. I superimpose custom painting on top of the image (overriding the drawRect method of the UIView), and it's very choppy when the background is the downloaded version, and very smooth when it's the embedded (and therefore optimized) version. Again, it's exactly the same file. The only difference is the optimization, which I'm hoping I can perform on the image at runtime, on the device, after downloading it.
Thanks again for everyone's help!
That link you posted pretty much answers your question.
During the build process XCode pre-processes your png so it's in a format that's more friendly to the graphics chip in the iPhone.
Png's that have not been processed like this will likely use a slower rendering path, one that deals with the non-native format and the fact that the alpha must be computed separately for each color.
So you have two options;
Perform the same work that pngcrush does and swap ordering/pre-multiply alpha. The speed up may be due to one or both of these.
After you have loaded your image, you can "create" a new image from it. This new image should be in the iPhone's native format and so should perform faster. The downside is it could potentially take up a bit more memory.
E.g.
CGRect area = CGRectMake(0, 0, width, height);
CGSize size = area.size;
UIGraphicsBeginImageContext(size);
[oldImage drawInRect:area];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The fact that you say it "seems" 100x slower indicates that you have not performed any experimentation, but made a guess (it must be the PNG optimization), and are now going down a path based on a hunch.
You should spend time to confirm what the problem is before you try to solve it. My gut says that PNG optimization shouldn't be the issue: that mostly affects the loading of images, but once they are in memory it doesn't matter what file format they were originally in.
Anyway, you should try an A-B comparison, either get your code to load an optimized PNG from somewhere else and see how it compares, or make a test app that just does some drawing on the two PNG types. Once you've confirmed what the problem is, then you can figure out if you need to compile pngcrush into your app.
On the surface, it sounds like something else is at play here. Any additional image manipulation should only add time until it's displayed onscreen...
Would it be at all possible to get the server to gzip the images by sending the appropriate HTTP header? (If it even helps file size much, that is.)
Temporarily using the pngcrush source might be a good test as well, just to get some measurements.
Are you storing the png at the original downloaded size? If it's a large image it'll take significantly longer to render.
Well it seems that a good way to do it (since you can't run pngcrush on the iPhone and expect that to speed it up) would be to make your requests through a proxy that runs pngcrush. The proxy would have nice horse power to actually give you some gain over the 100x pain you feel.
try pincrush to trans the normal png file to the crushed png file
You say you are drawing on top of the image by overriding a UIView's drawRect: method. Are you trying to do some animation by repeatedly drawing the whole image with your custom stuff on top of it?
You might get better results if you put your custom stuff in a separate view or layer, and let the OS deal with compositing the result over the background. The OS will only update the parts of the screen that you actually change, and won't be repainting the entire image as often.