22

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,

  1. background.jpg (as normal 1x image)
  2. 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

  1. 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..
  2. 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.

Krishnabhadra
  • 34,169
  • 30
  • 118
  • 167
  • 1
    I think that PNGs are better for displaying images on mobile devices - they are small, support alpha channel and need no compression. And there are no problems with `@2x`. :) – akashivskyy Jul 06 '11 at 11:17
  • I know..I always use png's..But in this case I have a lot of images (background is one of many case), and all of them are jpgs...So before converting everything to png, I thought I should ask here...After all documentation say jpg's are supported with UIImage.. – Krishnabhadra Jul 06 '11 at 11:19
  • 1
    Why do you want to use jpg? png should be preferred whenever possible on iOS. Edit: Kashiv was faster. :) I'd go with a batch converter... – Eiko Jul 06 '11 at 11:21
  • @Eiko, ya batchConverter is one option..But still I cant believe, after full one year of iOS4 in this world, nobody noticed this problem.. – Krishnabhadra Jul 06 '11 at 11:34
  • 1
    Additionally png's are recommended for iOS as Apple does some "optimizations" when you compile making the png's more efficient for the device to load but these optimizations also make the png no longer viewable on other devices. Jeff Lamarche discusses here http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html – Paul.s Jul 06 '11 at 11:43
  • @Paul, thanks for the reply, But my png files are working fine..I am seeing 1x and 2x png image on iphone. I am having problem when I use jpg's. – Krishnabhadra Jul 06 '11 at 11:56
  • 1
    How did you generate your @2x jpg image? It seems like minute pixel variations can put off things... Here is a good read on this topic http://globalmoxie.com/blog/designing-for-iphone4-retina-display.shtml. Always scale down, take the @2x image, and resize it to 50% and use it as your 1x image, works for me always. – Santthosh Jul 14 '11 at 20:15
  • @Santthosh, * Always scale down, take the @2x image, and resize it to 50% and use it as your 1x image* hmm, that is exactly what I have done.. *It seems like minute pixel variations can put off things* , I too first thought it was some problem with image, Then I wrote a wrapper like @Chandan has given in his answer, and run with jpg images, and 2x and 1x image worked well.. I am having problem only when I refer to image without extension.. – Krishnabhadra Jul 15 '11 at 03:07
  • 1
    I have also had problems when I stored the 2x file and the 1x file in separate folders. Using the same images, separate folders gave spotty 2x usage, same folder work perfectly... go figure. – Steven Veltema Mar 14 '12 at 06:15
  • We can use this online tool to convert png to ios 1x,2x,3x images https://www.workversatile.com/convert-png-to-ios-1x-2x-3x-image – Arshad Shaikh Aug 23 '22 at 18:17

5 Answers5

11

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:

  1. It's possible that the problem comes from the cache if you changed your images at some point.

  2. 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.

  3. 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.

PengOne
  • 48,188
  • 17
  • 130
  • 149
  • *I tried to reproduce this potential bug, but it worked as expected for me without the filename extensions* you mean you got jpg images working without filename extension? then it has to be some problem with my image – Krishnabhadra Jul 15 '11 at 03:14
  • *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*.. from the start of the project, iOS 4.0 and later is targeted..Also all my other images (which are png's) are referred without extension from the start, and they worked fine (saying that I never build this app targeting OS before 4.0).. – Krishnabhadra Jul 15 '11 at 03:16
  • @krishnabhadra... yes, i started with jpgs without extensions and they loaded fine. i had no pngs and nothing complicated (dummy app just to test this). very strange. – PengOne Jul 15 '11 at 05:25
7

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");
Chandan Shetty SP
  • 5,087
  • 6
  • 42
  • 63
  • Good thinking @Chandan..I have already written a similar wrapper and it worked beautifully..But I still changed my images to png to use Apple's native imageNamed and reduce the work load (since I have a lot of images in my project)..But your code is very useful.. – Krishnabhadra Jul 13 '11 at 09:29
  • 1
    changing .jpg files to .png will increase the image size hence the bundle size... If it is not a problem then fine. – Chandan Shetty SP Jul 13 '11 at 09:36
  • *changing .jpg files to .png will increase the image size hence the bundle size* ... Are you sure about that? I thought png's are more light weight.. – Krishnabhadra Jul 13 '11 at 10:04
  • .png images contain alpha... So the size will be more. Just check the size of single .jpg and verify it with by converting the same file to .png – Chandan Shetty SP Jul 13 '11 at 11:31
  • But for displaying images in mobile devices png's are better see http://mobile.tutsplus.com/tutorials/mobile-design-tutorials/mobile-design_png-or-jpg/ and http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html – Krishnabhadra Jul 13 '11 at 12:20
  • Ya i know that apple recommends .png image... Since u r converting .jpg to .png I just mentioned the fact that image size will be increased. – Chandan Shetty SP Jul 13 '11 at 15:42
5

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

Oliver Pearmain
  • 19,885
  • 13
  • 86
  • 90
  • 1
    Im using an asset catalog, and this fixed my problem! – João Nunes Oct 11 '14 at 11:41
  • @JoaoNunes note I was already using an asset catalog. I originally wasn't but there are further, additional iOS8/Xcode 6.0 bugs with JPGs when using within a launch screen XIB. See here... http://stackoverflow.com/questions/26139254/3x-images-incorrectly-used-on-iphone-6-or-5s-or-5-in-xibs-with-the-use-as-lau/26140455#26140455 – Oliver Pearmain Oct 12 '14 at 08:38
  • today i might send a bug report to apple regarding JPG and storybaord images and UIImage named – João Nunes Oct 13 '14 at 07:41
  • 1
    I just added a bug report: 18631644 – João Nunes Oct 13 '14 at 10:48
  • Good work my man, I thought about creating a ticket but I couldn't reproduce reliably. Are you able to copy the details to http://openradar.appspot.com so that they're publicly visible? – Oliver Pearmain Oct 13 '14 at 11:16
1

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.

Dancreek
  • 9,524
  • 1
  • 31
  • 34
  • I already tried as you have suggested. I mean I have used the exact same line of code as you have in the answer. And I am getting the image on my 3GS phone. But my iphone 4 is also displaying my 1x image, and it seems stretched and unclear.. – Krishnabhadra Jul 09 '11 at 03:18
  • I guess it's not a programmatically issue. Have you checked the correct linking of your background@2x.png file to your XCode project? Do you have the same issue with the iOS Retina Simluator? – Florian Mielke Jul 12 '11 at 08:15
  • sorry @Florian..didn't see your comment..Ya I am having the same issue in iphone simulator too.. – Krishnabhadra Jul 13 '11 at 10:02
-1

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

Elmo
  • 407
  • 4
  • 15
  • 1
    Yes @elmo, When I give image name with extension jpg images are displaying fine. But when I give **[UIImage imageNamed:@"Morbo"]** then jpg images are not showing...But when I give extension 2x images are not loaded in iphone 4...I think you have not read my question correctly.. – Krishnabhadra Jul 13 '11 at 02:29
  • 1
    Sorry you're right, dyslexia is a bit of a curse for a programmer ;) thought the general implication was that jpgs cant be used. I just remember first trying to use images and when they didnt work I just added the extension like in web programming – Elmo Jul 13 '11 at 08:03
  • I am sure jpg's can be used..I got it working..The only question is whether **UIImage imageNamed:** handles jpg image the same way as png's...For png's they understand 1x and 2x images without giving extension..But for jpg's they simply takes nothing without extension.. – Krishnabhadra Jul 13 '11 at 08:26