Loaded image in UIImage is pixelated on retina - iphone

I parsed the data from a web which also contains jpg image. The problem is that the image looks blurry/pixelated on retina display. Any solution for this? Thanks.
NSData *data = [NSData dataWithContentsOfURL:linkUrl];
UIImage *img = [[UIImage alloc] initWithData:data];
// detailViewController.faces.contentScaleFactor=[UIScreen mainScreen].scale;//Attampt to solve the problem
detailViewController.faces.image=img;

After initializing your image with the data, create a new one from it with the correct scale like this:
img = [UIImage imageWithCGImage:img.CGImage scale:[UIScreen mainScreen].scale orientation:img.imageOrientation];
...but note that the image will now appear half the size on retina displays unless you scale it up, for example by stretching it in an image view.

Related

iphone: Scale the image in table cell

I am using a UITableViewCellStyleSubTitle. I am trying to add thumbnails to my table cells.
UIViewContentModeScaleAspectFit does not seem to work for reasons unknown. I have seen a lot of answers in stack overflow for similar kind of questions. If i crop the image using drawInRect it works, like this
[thumbnail drawInRect:thumbnailRect];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
But what i am trying to achieve should not need me to do this. I am only trying to scale the image and not crop it.
So setting the content mode to "UIViewContentModeScaleAspectFit" for the imageview of the default cell should work.. but it does not.
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
Complete logic for setting thumbnails.. fPath is the path to image
UIImage *thumbnail = [UIImage imageWithContentsOfFile:fPath];
[cell.imageView setImage:thumbnail];
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
cell.imageView.clipsToBounds = YES;
I found out that drawInRect stretches the original image if the size is lower or croppes it if it is bigger.
This article will help you to prepare a thumbnail of your image
http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/
It has several useful UIImage classes extentions:
* UIImage+Resize
* UIImage+Alpha
* UIImage+RoundedCorner
Example Usage:
UIImage *imageThumb = [YourImage thumbnailImage:70 transparentBorder:0 cornerRadius:10 interpolationQuality:kCGInterpolationHigh];
and then you can use drawInRect method. If the image is not rectangle - the image will crop the bigger side and take the middle of the image
Hope this answer will guide you.

Orientation does not behave correctly with Photo in ALAsset

I current have an app that uses ALAsssetsLibrary to fetch the photos. I have placed the photo to an image view and I am able to upload to the server. When I tested on the real device after taking some photos, I found out the photos that supposed to be taken in Portrait become a landscape.
Therefore, I called different function to get the CGImage like this:
UIImage *image = [UIImage imageWithCGImage:[representation fullResolutionImage] scale:1.0 orientation:(UIImageOrientation)[representation orientation]];
The first tried out, I used this :
UIImage *image = [UIImage imageWithCGImage:[representation fullResolutionImage]]
I thought the one with scale and orientation could give me the right orientation that the photo was taken. But it didn't give me the right solution.
Do I miss anything that is necessary to generate a correct orientation of photo?
The correct orientation handling depends on the iOS version you are using.
On iOS4 and iOS 5 the thumbnail is already correctly rotated, so you can initialize your UIImage without specifying any rotation parameters.
However for the fullScreenImage, the behavior is different for each iOS version. On iOS 5 the image is already rotated on iOS 4 not.
So on iOS4 you should use:
ALAssetRepresentation *defaultRep = [asset defaultRepresentation];
UIImage *_image = [UIImage imageWithCGImage:[defaultRep fullScreenImage]
scale:[defaultRep scale] orientation:(UIImageOrientation)[defaultRep orientation]];
On iOS5 the following code should work correctly:
ALAssetRepresentation *defaultRep = [asset defaultRepresentation];
UIImage *_image = [UIImage imageWithCGImage:[defaultRep fullScreenImage] scale:[defaultRep scale] orientation:0];
Cheers,
Hendrik
Try this code:-
UIImage* img = [UIImage imageWithCGImage:asset.thumbnail];
img = [UIImage imageWithCGImage:img.CGImage scale:1.0 orientation:UIImageOrientationUp];
This may help you.
My experience is limited to IOS 5.x but I can tell you that the thumbnail and fullscreen images are oriented properly. It's the fullresolutionimage that's horizontal when shot vertically. My solution is to use a category on uiimage that I got from here:
http://www.catamount.com/forums/viewtopic.php?f=21&t=967&start=0
It provides a nice rotating method on a UIImage like this:
UIImage *tmp = [UIImage imageWithCGImage:startingFullResolutionImage];
startingFullResolutionImage = [[tmp imageRotatedByDegrees:-90.0f] CGImage];
For fullResolutionImage, I'd like to provide a solution as follows,
ALAssetRepresentation *rep = [asset defaultRepresentation];
// First, write orientation to UIImage, i.e., EXIF message.
UIImage *image = [UIImage imageWithCGImage:[rep fullResolutionImage] scale:rep.scale orientation:(UIImageOrientation)rep.orientation];
// Second, fix orientation, and drop out EXIF
if (image.imageOrientation != UIImageOrientationUp) {
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
[image drawInRect:(CGRect){0, 0, image.size}];
UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
image = normalizedImage;
}
// Third, compression
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
imageData is what you want, and just upload it to your photo server.
By the way, if you think EXIF is useful, you can complement it to normalizedImage as you wish.

Adding thumbnail size images to tableview

I have a tableview, and i am loading images to it. I have images which are ranging from 150kb - 2MB. Since this is too much for a tableview to handle (it takes long time to load, and makes the scrolling slow), i thought of using ImageIO framework to create thumbnail images of images.
I found a code that does this, but i can't undestand it.
1.) Can someone please explain me the code
2.) My problem is that, I have a tableview and i need to load thumbnail images to it. So how can i use the following code and display it on my tableview. Can someone show me some sample code or a tutorial that does this ?
heres the code ;
-(void)buildGallery
{
for (NSUInteger i = 0; i < kMaxPictures; i++)
{
NSInteger imgTag = i + 1;
NYXPictureView* v = [[NYXPictureView alloc] initWithFrame:(CGRect){.origin.x = x, .origin.y = y, .size = _thumbSize}];
NSString* imgPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%d", imgTag] ofType:#"jpg"];
CGImageSourceRef src = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:imgPath], NULL);
CFDictionaryRef options = (CFDictionaryRef)[[NSDictionary alloc] initWithObjectsAndKeys:(id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform, (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent, (id)[NSNumber numberWithDouble:_maxSize], (id)kCGImageSourceThumbnailMaxPixelSize, nil];
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options); // Create scaled image
CFRelease(options);
CFRelease(src);
UIImage* img = [[UIImage alloc] initWithCGImage:thumbnail];
[v setImage:img];
[img release];
CGImageRelease(thumbnail);
}
}
Basically the problem you have is due to the fact that when you scale down an image, the number of bytes stored in memory doesnt change when you scale it down. The hardware still has to read your 2mb image, and then render it to a smaller scale. What you need to do is to either change the size of your image (use photoshop or other) or the way im suggesting is to compress your image, and then scale it down. The image will look rough at normal size, but will look ok when you scale it down to a thumbview.
To generate an NSData version of your image encoded as a PNG.
NSData *PNGFile = UIImagePNGRepresentation(myImage);
Or a JPEG, with a quality value set
NSData *JPEGFile = UIImageJPEGRepresentation(myImage, 0.9f);
Both of these will give you an image smaller than you currently have, which will be easier to render in the tableView.
In order to get better performance you're going to have to load the image in a background thread, and after it's in memory add the UIImage to the image view on the main thread. There are a couple ways to go about doing this, but the simplest is going to be using GCD's block based methods.
Resizing the image is definitely still important for memory considerations, but get the asynchronous image loading part down first.

iOS UIImageJPEGRepresentation error: Not a JPEG file: starts with 0xff 0xd9

I am writing a .jpg file to my app's Documents directory like this:
NSData *img = UIImageJPEGRepresentation(myUIImage, 1.0);
BOOL retValue = [img writeToFile:myFilePath atomically:YES];
Later, I load that image back into a UIImage using:
UIImage *myImage = [UIImage imageWithContentsOfFile:path];
I know it works because I can draw the image in a table cell and it is fine. Now if I try to use UIImageJPEGRepresentation(myImage, 1.0), the debugger prints out these lines:
<Error>: Not a JPEG file: starts with 0xff 0xd9
<Error>: Application transferred too few scanlines
And the function returns nil. Does anybody have an idea why this would happen? I haven't done anything to manipulate the UIImage data after it was loaded. I just provided the UIImage to an image view in a cell. I set the image view properties such that all the images in the cells line up and are the same size, but I don't think that should have anything to do with being able to convert the UIImage to NSData.
The images were not corrupt, I was able to display them correctly. The issue is possibly a bug in UIImage, or perhaps the documentation should be more clear about using imageWithContentsOfFile:.
I was able to eliminate the error message by changing
UIImage *myImage = [UIImage imageWithContentsOfFile:path];
to
NSData *img = [NSData dataWithContentsOfFile:path];
UIImage *photo = [UIImage imageWithData:img];

How to display the UIImageJPEGRepresentation image in iphone sdk

I want to use UIImageJPEGRepresentation to add the image in iphone, in below code i am missing some thing I don't know how to add
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:gameObj.gameThumbnails]];
UIImage *myImage=[UIImage imageWithData:data];
imageView.image=UIImageJPEGRepresentation(myImage, 90);// I am missing something here
[elementView addSubview:imageView];
[imageView release];
/*gameObj.gameThumbnails is an url like http://static.gamesradar.com/images/mb/GamesRadar/us/Games/X/X-Men%20Arcade/Bulk%20Viewer/360%20PS3/2010-10-11/192.168.30.167-image36_bmp_jpgcopy--game_thumbnail.jpg
*/
Please help me out of this
u are setting comparison quality to 90. it should be between 0.0 to 1.0
The UIImageJPEGRepresentation function returns an NSData (array of bytes) which represents a content of the image if compressed in JPEG.
To display it, you just need to use the UIImage directly.
imageView.image = myImage;
Make sure that you:
Set your compression quality to 0.9(it MUST be between 0.0 - 1.0)
Set the frame of the UIImageView correctly
Don't make that UIImageView hidden
And if it still doesn't work then try the following:
[elementView bringSubviewToFront:imageView];
Hope it helps