Image tiles on iPhone 4 - iphone

I am very new to iPhone development, and I am working on modifying an app which was written a year ago. Recently with the release of the new iphone 4 we have noticed that the screen which was previously displaying an image just fine, has not started to tile that image. And instead of one large image I am now seeing 4 smaller ones. I have tried increasing the size of this image but that does not help. Anyone know what this can be? Resolution? How do I fix this?
Thanks,
Natasha

You need to create another double-resolution version of the file with #2x in the filename. For example, if your original graphic is
tile.png
You need to create your double-resolution one as:
tile#2x.png
This will be used on the iPhone 4 and should fix your problem.
Update
If you have no control over the images you will have to detect whether you are running on a high-resolution device and set the contentScaleFactor property on the image appropriately. Something like this:
UIScreen *screen = [UIScreen mainScreen];
if ([screen respondsToSelector:#selector(scale)] &&
[imageView respondsToSelector:#selector(setContentScaleFactor:)]) {
/* Set image view's scale factor to that of the native screen */
[imageView setContentScaleFactor:[screen scale]];
}
This uses an imageView, but it sounds like in your case a view is using a [UIColor colorWithPatternImage:...] on its background, so you may have to set the scale on something else. This might affect the position of subviews as well.
Why are you not able to create a new #2x version of the image and include it in your bundle?

Related

Create images for iphone and ipad, 4 images?

When i create an image for an ImageView to iPhone, iPhone retina, iPad, iPad retina, should i create 4 images ?
For example for a coin image that i use ->
coin.png
coin#2x.png
coinIpad.png
coinIpad#2x.png
Can i create just the most-size image (imageIpad#2x.png) and inside Xcode select Aspect Fit ?
[UIImage imageNamed:#"imageIpad#2x.png"];
Which is the common way to do this?
To answer you question as you asked it: Yes you can just use the highest resolution image only and have it fitted to the size that each device currently needs. You can to that by just initializing the UIImage with the named resouce, as you suggest, and assign that to an UIImageView with an appropriate frame in each device type.
Would I advice doing so? No!
Why?
The naming conventions (~ipad and #2x) make it easy for you as programmer to provide perfectly fitted artworks for each resolution.
You or your designer respectively are in full control over how the artworks will be displayed
It saves memory and cpu and therefore even a bit of battery power.
When it comes to very detailed or small graphics that don't rezise well, then you can consider creating slightly different ones for the lower resolutions that suit better for their current resolution
So if you just want to downsize a high-res image then download something powerful but cheap like gimp and reszise it once yourself (instead of having thouthands of mobile phones do it again and again), save them with poper names and include them in the boundle.
Creating only one image and relying on the device to resize it is:
Inefficient - you're going to be using a lot of resources at runtime that should be busy doing other things
Not the intended way - you should create 2 images (retina and non-retina). If you wish to use another set of images for iPad, you should either check which device you're running on at runtime by using:
[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad
or by splitting your project into 2 separate targets and adding the 2 sets of images separately to their correct target.
All you need to do is to put coin when you want to call it.
For example:
[UIImage imageNamed:#"coin"];
But when put the images in the resources folder, name it as coin#2x.png for retina image and coin~ipad.png for ipad images.
Xcode will call the appropriate image accordingly.
If you just want to have resizable assets that you can create once and use in different situations - have a look at this UIImage+PDF category that helps you use a PDF, which as a vector format can be scaled to whatever size without loss of quality.
Cacheing has been recently added, which should be a help as well.

iPhone4 UI design vs iPhone5

I have a next problem. I was searching in Google and here but still not found correct and proper solution. I have application which has to run on iPhone 4 and on iPhone 5. As we know iPhone 5 has a different screen size then 4th one. Let's see simple case, I have a view controller with background image. Image is size sensitive and if I will stretch it it will look ugly. So I have two different images one image for old 4th resolution and and another image for new 5th one. The question is what is the best and let's say "native" way to implement correct image showing on the both devices.
I see simplest way to do it is making runtime checking which device currently used and set proper image name to UIImageView. But I find it ugly. Does somebody know the correct way to do it?
You can use:
#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)
Then,
if (IS_IPHONE5) {
//iPhone5
} else {
/older devices
}
Source: How to get the actual [UIScreen mainScreen] frame size?

jpg images in iphone and 2x images

I am working on an iphone app and targeting iOS 4.0 or later. I am trying to add an image to UIImageView, and image is in jpeg format. This is what I have done so far..
UIImageView *bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 246.0)];
bgImageView.image = [UIImage imageNamed:#"background"];
[self.view addSubview:bgImageView];
[bgImageView release];
I have added two images,
background.jpg (as normal 1x image)
background#2x.jpg (for 2x / retina
display).
But when I build and run, everything runs fine, except there is no background. All my other widgets are there, but there is a white background and image is not showing.
Next I created two png images for my background, added it to the project and ran. This time my background was shown. I was perplexed because according to documentation jpg image can be used in iphone with UIImage.
I tried again with my jpg images and changed the code above to this
UIImageView *bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 246.0)];
bgImageView.image = [UIImage imageNamed:#"background.jpg"]; //added extension
[self.view addSubview:bgImageView];
[bgImageView release];
When I run the above code, background image is showing, but 2x images are not loaded. That shows my jpg image is fine, and it is not the culprit. So when I just give image name without extension, png files (both 1x and 2x)are loaded on respective devices, jpg files are not loaded at all.
Looks like a bug (either in sdk or documentation). iOS 4 is here for a good year. why no one noticed it? Also is there any option for me other than to convert all my images to png?
EDIT :
Well, two days in to the question, zero answers. I have already converted all my images to png, and that part of my project is done (as my project couldn't wait..). Still, for my own sake and for sake of everyone who faces this in future, I would like to know more about this problem. At least someone can confirm that this is indeed an apple bug. I am starting a bounty so that more people can see this thread.
EDIT AGAIN
2 days remaining for this bounty to end. Thanks for everyone who responded. But let me clarify one thing. I have already said that I have converted all my images to png and I moved along. I just wanted some confirmation that imageNamed treats jpg and png files same way. Documentation certainly says it will(unless Apple has written it somewhere other than UIImage documentation). If documentation is correct then my code failed me because of two possible reasons
It is a bug in imageNamed. If this is the reason, then I dont have too much option other than file a bug report, change my images to png or write a wrapper(like Chandan has said in his answer) and move on..
There is some problem with the jpeg image I used. Well I am not a photoshop guy. But I used
RGBA jpg image. If image does matter I am ready to ask my designer
friend and provide more info.
One more thing. This post also just tells about this problem. But he dont know the reason behind. So I am not alone.
EDIT : THE END
Well it is something related to the image itself. I googled and downloaded some sample jpeg images and played with it. Some of them shown up correctly and some doesn't. Since the boundy time is up, I am giving the boundy to PengOne who tried to reproduce the bug and successfully loaded jpg image without extension, there by making me to work with more images. Thanks for everyone who tried to help.
According to the UIImage Class Reference:
Discussion
This method looks in the system caches for an image object with the
specified name and returns that object if it exists. If a matching
image object is not already in the cache, this method loads the image
data from the specified file, caches it, and then returns the
resulting object.
On a device running iOS 4 or later, the behavior is identical if the
device’s screen has a scale of 1.0. If the screen has a scale of 2.0,
this method first searches for an image file with the same filename
with an #2x suffix appended to it. For example, if the file’s name is
button, it first searches for button#2x. If it finds a 2x, it loads
that image and sets the scale property of the returned UIImage object
to 2.0. Otherwise, it loads the unmodified filename and sets the scale
property to 1.0. See iOS Application Programming Guide for more
information on supporting images with different scale factors. Special
Considerations
On iOS 4 and later, the name of the file is not required to specify
the filename extension. Prior to iOS 4, you must specify the filename
extension.
Since you're targeting iOS 4.0 and later, you should not need the filename extension. I tried to reproduce this potential bug, but it worked as expected for me without the filename extensions.
Here are some ideas for what may have gone wrong to create this effect in your app:
It's possible that the problem comes from the cache if you changed your images at some point.
If you choose not to use the filename extensions, and you have both "background.jpg" and "background.png" as options, the preference appears to be to use the ".png" file.
If you set the target to iOS 4.0 and later after first running the app, then the filename extension would have been required and the image may have been cached blank, which leads back to theory 1.
That's the best I can make of this.
Write a wrapper to get the image like
-(UIImage*) getImage:(NSString*)imageName{
UIImage *image;
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) {
// RETINA DISPLAY
NSString *jpegFile = [imageName stringByAppendingString:#"#2x.jpg"];
image = [UIImage imageNamed:jpegFile];
}
else{
NSString *jpegFile = [imageName stringByAppendingString:#".jpg"];
image = [UIImage imageNamed:jpegFile];
}
return image;
}
And from your code call
bgImageView.image = getImage(#"background");
With the dawn of Xcode 6 I have found that JPG images might not render at all on certain iOS7 devices (they may work on some but not on others, or they may not work on any, and you may see a different result on a different developers machine, there doesn't seem to be any consistency). This is regardless of whether the image is just referenced in UIImageView in a XIB or programmatically with [UIImage imageNamed:] (which returns nil).
After scratching my head for a long time, the solution was to rename the *.jpg file extension to *.png (whilst obviously leaving the file contents as JPG data).
HTH
You just need to provide the full name of image.
bgImageView.image = [UIImage imageNamed:#"background.jpg"];
don't leave off the extension.
As for the #2x, it is not necessary to call it out anywhere in the code. If you code correctly there is no need to test for a retina display as some here have suggested.
You can use jpgs, just tried it myself and it worked. Only suggestion is how you are instantiating it.
Try it this way:
stockImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"Morbo.jpg"]];
stockImage.frame = CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height) ;
[self.view addSubview:stockImage];
This is the image I used:
http://futurama.wikia.com/wiki/File:Morbo.jpg

setting size of UIImageView in a UITableView cell programmatically - what is the origin?

I'm trying to set the size of a UIImageView programmatically using:
[thisImageView setFrame:CGRectMake(x, y, image.size.width, image.size.height)];
I tried using x = 0, y = 0, but the UIImageView disappears.
More info on why I'm trying to do this. I'm trying to display a high-res image on an iPhone 4 without using the iOS 4 SDK (only using 3.2 SDK API calls). I have calls to see if I'm on an iPhone 4, so I'm trying to double the size of my UIImageView so that when I put the high-res UIImage in, it won't be grainy.
Not sure what there is so special about iOS. Just use the same method you use with 3.2: imageNamed: ... it will take care of everything as long as your images are named properly (yourimagename.png and yourimagename#2x.png). Nothing fancy in the iOS 4 SDK here, just give the size you use in points as before.
If this is not suitable in your case, can you explain why?
I'm trying to display a high-res image on an iPhone 4 without using the iOS 4 SDK (only using 3.2 SDK API calls)
Ouch. Don't do that.
Compile against 4.0, set the deployment target to 3.whatever.
When creating the image, check [UIImage respondsToSelector:#selector(imageWithCGImage:scale:orientation:)]. If it does, then you can use +[UIImage imageWithCGImage:scale:orientation:] to create a "scale 2" image, which will display correctly in a UIImageView on iPhone 4 (which has a "scale 2" screen).
If you really can't use the OS 4 SDK (you don't seem to state a reason why), then make the UIImageView smaller using the appropriate content mode (AspectFit/AspectFill/ScaleToFill), and set its frame to half the size in pixels (e.g. if the image is 100x100 px, set it to (CGSize){50,50}). This shrinks the image to half-size, but the double-res screen means you see it pixel-for-pixel.
I think your approach is wrong. iPhone 4 works with points instead of pixels, which makes doubling the size troublesome. 1 point on old devices equals 4 pixels on iPhone 4, but is still used as 1 point.
When you create the frame you're not actually giving the API the pixel dimensions, but the point dimensions.

Image overlapping in photo viewer on three20 framework?

I just integrated the photo viewer from three20 framework. Its working fine but some time images are overlapping, that ia happening only for thumnail image while original image is perfectly loaded. Till the original image loaded , at that point of time images are overlapping.
Did any one face this problem and have any solution for that?
Thanks
If images are overlapping, you are not correctly setting their size when you are including them in the photo view controller. You have to (unfortunately) tell three20 the exact size so it knows how to display them in paging mode of the scrollview.
Make sure you are resizing your thumbnails similar sizes to his (somewhere around 100 pixels tall or wide, based on if it's in portrait or landscape)
[[[MockPhoto alloc]
initWithURL:#"http://farm4.static.flickr.com/3444/3223645618_13fe36887a_o.jpg"
smallURL:#"http://farm4.static.flickr.com/3444/3223645618_f5e2fa7fea_t.jpg"
size:CGSizeMake(320, 480) // see how he sets the size here for each and every photo? this is crucial
caption:#"These are the wood tiles that we had installed after the accident."] autorelease],
If you look at the thumbnail, it is 67pixels by 100pixels: http://farm4.static.flickr.com/3444/3223645618_f5e2fa7fea_t.jpg
If you look at the regular photo, it is 320pixels by 480pixels. : http://farm4.static.flickr.com/3444/3223645618_13fe36887a_o.jpg
These are two independent files, the three20 code does not create the thumbnail for you based on the larger photo. You must do this manually or subclass whatever container class he uses to do it for you.
Just by setting line 135 of TTPhotoView.m to
self.contentMode = UIViewContentModeScaleAspectFit
will help.