iphone 4 images lose resolution - iphone

I have the following 2 issues with iPhone 4 images. Any help is appreciated.
When using iPhone 4 if I access an image from photo library in my app and save it in a database, then retrieve it again, I see it has lost resolution. The same works fine on 3G - no loss of resolution. Any idea why this could be happening?
I am using retina scan images on iPhone 4 for buttons. They are set directly from the IB. Sometimes I see they are skewed to half the height and same width. Again, this is not seen on 3G and everything works fine.
Any help is much appreciated.
Here's the code which I use to access from library. I dont think saving to database is causing it. I am using an "ImageToDataTransformer".
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *img;
img = [self scaleAndRotateImage:[info objectForKey:UIImagePickerControllerOriginalImage]];
imageView.image = [img imageByScalingProportionallyToSize:targetSize];
}
In scaleAndRotateImage I use "static int kMaxResolution = 640;" Will this work for iPhone 4? May be this could be the issue.
Code for scaleAndRotateImage is found here

These are really two separate issues.
For saving the images, I'm guessing that somewhere you're calling UIGraphicsBeginImageContext. Instead you should use UIGraphicsBeginImageContextWithOptions. This link has more details. (If you want to support both 3.x and 4.x devices, you'll have to check that the function exists before you call it. See here for details on how to do this. If it doesn't exist, call the original method instead.)
The button issue is harder to diagnose. Make sure your "#2x" images are named correctly (including case sensitivity), and they really are exactly double resolution. Beyond that, it's hard to say. I would review this and double check that you're doing everything correctly.

Related

UIImage:imageWithContentsOfFile is 10 times slower in iOS 5.0

After simply recompiling our iPhone application on newly released iOS 5.0 SDK i faced strange problem - all UIImage:imageNamed (first call with actual image loading) and UIImage:imageWithContentsOfFile started to work 10 times slower than before. i managed to narrow problem down: this is the case only for jpeg and png files (not gifs!) and this is not because of file size. even straightforward loading of small 32*32 png takes around 300ms... compared to 30ms on older devices (checked on 3.1 and 4.3.5 with the exact same code)
i also tried to load image via newly introduced CIImage with this code
WLLog(#"Data loading...");
NSData *imageData = [NSData dataWithContentsOfFile:path];
WLLog(#"CIImage creation...");
CIImage* cii = [CIImage imageWithData:imageData];
WLLog(#"CIImage creation ok...");
float scle = 1.0;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
scle = [[UIScreen mainScreen] scale];
}
#endif
CIContext *context = [CIContext contextWithOptions:nil];
UIImage* res5 = [[UIImage alloc] init];
WLLog(#"UIImage creation...");
[res5 initWithCGImage:[context createCGImage:cii fromRect:cii.extent] scale:scle orientation:UIImageOrientationUp];
WLLog(#"Done!");
without any luck... this single line
CIImage* cii = [CIImage imageWithData:imageData];
takes the same 300ms even on small images (4Kb png). imho, there is simple nothing to parse at all!
Is there anything to resolve such strange change in loading times? For now it looks like something changed drastically in sdk internals :(
I had the same problem and it took me a few hours to find out what went wrong. Our two situations seemed to be exactly the same: An old project that didn't run very well on iOS5 any more.
So I took Instrument's Time Profiler and dug into the depth of my app only to find out that every time the app hung it actually was in the process of opening PNG files for UIImageViews, just like you found out as well.
But other apps I wrote don't have this problem, and I did everything the same way. So judging by what you experienced and that my other apps were running fine, I figured it must have something to do with the PNG files themselves. And guess what, it turned out that I was right.
So I sat down and wrote a script that piped all PNG files through ImageMagick's convert to make TGAs out of them, then deleted the PNGs (just for good measure) and then converted the temporary TGAs back to PNG files. That way I made sure that they were not only NOT created by Photoshop any more, but also completely rewritten.
That did the trick. Everything runs smoothly now, just as it did on iOS 3 and 4.
I'm not sure if it had something to do with Photoshop. Other apps I recently did work fine with PNGs made with Photoshop. So maybe it was the version of Photoshop I used pretty much exactly a year ago to create those PNGs in the first place.
Or maybe simply overwriting the old image files were enough, I'm not sure. But now it runs just fine.
I hope this helps!
It could very well be a bug. Submit a radar to Apple via the bug reporter. Be sure to throw together a simple project which clearly demonstrates the bug and attach it to the bug report -- otherwise Apple will send you an email asking for one.
Post your radar # here so others with a similar issue can reference that # when submitting a similar bug to Apple as well.

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

App failing to see #2x images

This is driving me nuts. Been searching for 2 days, and I can't find any real solution or explanation for why this is happening. I know there are threads here on SO, as well as some other places, but they have been no help. I have read the Apple documentation on the matter.
I have normal and #2x images in my app. They are named correctly (edit_image.png, and edit_image#2x.png). They are sized correctly (normal is 60x60, #2x is 120x120). They are both being copied into the app bundle, and when I examine the contents, I can see them both in the root.
I am grabbing the image by calling [UIImage imageNamed:#"edit_image"]. It never grabs the 2x image. It only sees the 1x image. However, if I check the scale first, and use this code:
if ([[UIScreen mainScreen] scale] == 1) {
NSLog(#"test");
editImage = [UIImage imageNamed:#"edit_image"];
} else {
editImage = [UIImage imageNamed:#"edit_image#2x"];
}
Then it does grab the correct image. I have tried everything. I deleted the high res from the project, cleaned, re-added the high res, cleaned and then built, no dice. I deleted all the images, and re-added them, no dice. I have done everything I can think of. What the hell is going on here?
Are you creating universal application for both iPhone & iPad. If universal app is there then you need to create 3 set of images:
1) edit_image~iPad.png
2) edit_image~iphone.png
3) edit_image#2x~iphone.png
each with the same resolution of 72 pixels/inch. While you need to provide double size for that #2x image which I think you've already done this.
Now, try the below code
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"edit_image" ofType:#"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath];
Important: When creating
high-resolution versions of your
images, place the new versions in the
same location in your application
bundle as the original.
Source: http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/SupportingResolutionIndependence/SupportingResolutionIndependence.html
Two silly mistakes that I've made that can cause this problem:
Accidentally naming the small
versions #2x instead of the large
ones
Having the large versions be
slightly missized (by one pixel)
You don't need to add the "#2x" bit, or have the if-else logic at all. Just use [UIImage imageNamed:#"edit_image"].
I was suffering from the exact same problem, and finally found a solution (after 2 days of searching).
In my case the name of the #2x image didn't exactly match the normal sized image: tileSet.png and tileset#2x.png.
What made this so difficult to discover is that the #2x file did have the correct name in Finder and in XCode. I was only able to discover the problem by opening the image in Preview and looking at the Inspector. I don't know enough about the Mac file system to explain how this happens, but once I renamed the file to gibberish, then renamed it back to tileSet#2x.png everything started working as expected.

colorWithPatternImage with iPhone 4 Retina Display (image#2x.png)

Thanks to SO's search function blowing up whenever I enter "#2x", it's difficult to tell whether this has already been asked...
I've been using colorWithPatternImage: to build tiled background images for my various views. However, these predictably look like trash when viewed on the new iPhone 4 display. So I've built #2x versions of my tile.png files, yet colorWithPatternImage: evidently can't properly handle UIImages with double the scale.
Has anyone effectively developed a workaround for this issue? Perhaps within the CoreGraphics framework (of which, I'm quite the novice)?
I believe this is a bug with the SDK. colorWithPatternImage: is doing strange things with the HD image. There's a small thread on the Apple Dev Forums on it, but basically I think it's a bug. Not sure if Apple are aware of it just yet.
I've worked around it by drawing the pattern in a subclass of the view within -drawRect:.
Hope this helps.
- (void)drawRect:(CGRect)rect {
[[UIImage themeImageNamed:#"UIBackgroundPattern.png"] drawAsPatternInRect:rect];
}

UIImagePickerController returned image woes

I have a UIImagePickerController that lets the user pick an image from their library, edit it, and then save the product out to disk. Before it saves, however, I need to update a UIImageView to hold the edited photo. But when I go to set the UIImageView's image property, the program crashes. It still can save to disk.
The UIImageView is an IBOutlet and the dimensions are 88x88, if anybody cares.
I can reproduce this issue on a device (iPhone 3GS running iOS4) and in the simulator (iOS 4).
Don't you know what the error is? Especially in iOS4 you should see an entire stack trace in your log.
Most likely culprit would be a bad Interface Builder link... from there you should do retain count on your actual UIImage to see where it is when you assign it to the ImageView...
Anything after that, I suspect, would be application specific.