UIImageView contentMode different in retina and non-retina dispaly - iphone

So I have this UIImageView with an image on top of it. When I'm using normal iPhone display, it shows inside the UIImageView exactly as it supposed to - in the UIImageView bounds, the problem is when I'm using retina display device, the image becomes big and doesn't fit the UIImageView bounds, it goes all over the screen.
How can I fix this issue? I want the image in Retina display to fit inside the UIImageView size.
This is my code:
- (UIImage *)loadScreenShotImageFromDocumentsDirectory
{
UIImage * tempimage;
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES );
NSString *docDirectory = [sysPaths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/MeasureScreenShot.png", docDirectory];
tempimage = [[UIImage alloc] initWithContentsOfFile:filePath];
return tempimage;
}
- (void)viewDidLoad
{
// Setting the image
UIImage * Image = [self loadScreenShotImageFromDocumentsDirectory];
theImageView.frame = CGRectMake(0, 166, 290, 334);
theImageView.contentMode = UIViewContentModeCenter;
theImageView.image = Image;
}
Thank in advance!

Try setting the content mode to UIViewContentModeScaleAspectFit

When I was using an image with core plot, I had to scale the image for the retina display.
CPTImage *fillimage = [CPTImage imageWithCGImage:bubble.CGImage scale:bubble.scale];
the name of the image file was bubble and I had a bubble file and a bubble#2x file. This let the image fit the image view for either display. Hope this helps.

Related

incorrect image size in iPhone

I need to use image height and width.I have 800*800 pixel image in my ios simulator. But when i am finding the size of image using
image.size.width and image.size.height
it is giving me 315*120 which is incorrect why so?
- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info
{
NSLog(#"%#",info);
int temp = [[DataManager sharedObj] imageCount];
for(NSDictionary *dict in info)
{
[[DataManager sharedObj] setImageCount:temp+1];
NSMutableDictionary* dataDic = [[NSMutableDictionary alloc] init];
UIImage* img = [dict objectForKey:UIImagePickerControllerOriginalImage];
NSLog(#"%.2f",img.size.width);
NSLog(#"%.2f",img.size.height);
}
}
Try to call image.frame = cgrectmake(x, y, 800, 800).
If you have an UIImageView *image instead of UIImage *image, problably you get the frame of the view not the image.
SOLVED:
change fullScreenImage to fullResolutionImage in line 33 of your ELCImagePickerController.m.
You can get the image size by using this
UIImage *imageS = [dict objectForKey:UIImagePickerControllerOriginalImage];
NSLog(#"width = %.2f, height = %.2f", imageS.size.width, imageS.size.height);
NSLog(#"Image Size = %#",NSStringFromCGSize(imageS.size));
Both lines will work.
It will print right. Please check your simulator image once again. If you added it via google may me you have been saved the image thumbnail instead of original image thats why you are getting the size wrong. Otherwise method of getting image size is correct.

Loaded image in UIImage is pixelated on retina

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.

How to Define UIImageView size as UIImage resolution?

I have scenario, in which I am getting images using Web Service and all images are in different resolution. Now my requirement is that I want resolution of each Images and using that I want to define size of UIImageView so I can prevent my Images from getting blurred
For example image resolution if 326 pixel/inch the imageview should be as size of that image can represent fully without any blur.
UIImage *img = [UIImage imageNamed:#"foo.png"];
CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
UIImageView *imgView = [[UIImageView alloc] initWithFrame:rect];
[imgView setImage:img];
Image size IS it's resolution.
Your problem might be - retina display!
Check for Retina display and thus - make UIImageView width/height twice smaller (so that each UIImageView pixel would consist of four smaller UIImage pixels for retina display).
How to check for retina display:
https://stackoverflow.com/a/7607087/894671
How to check image size (without actually loading image in memory):
NSString *mFullPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
stringByAppendingPathComponent:#"imageName.png"];
NSURL *imageFileURL = [NSURL fileURLWithPath:mFullPath];
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageFileURL, NULL);
if (imageSource == NULL)
{
// Error loading image ...
}
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], (NSString *)kCGImageSourceShouldCache, nil];
CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, (CFDictionaryRef)options);
NSNumber *mImgWidth;
NSNumber *mImgHeight;
if (imageProperties)
{
//loaded image width
mImgWidth = (NSNumber *)CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelWidth);
//loaded image height
mImgHeight = (NSNumber *)CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
CFRelease(imageProperties);
}
if (imageSource != NULL)
{
CFRelease(imageSource);
}
So - for example:
UIImageView *mImgView = [[UIImageView alloc] init];
[mImgView setImage:[UIImage imageNamed:#"imageName.png"]];
[[self view] addSubview:mImgView];
if ([UIScreen instancesRespondToSelector:#selector(scale)])
{
CGFloat scale = [[UIScreen mainScreen] scale];
if (scale > 1.0)
{
//iphone retina screen
[mImgView setFrame:CGRectMake(0,0,[mImgWidth intValue]/2,[mImgHeight intValue]/2)];
}
else
{
//iphone screen
[mImgView setFrame:CGRectMake(0,0,[mImgWidth intValue],[mImgHeight intValue])];
}
}
Hope that helps!
You can get image size using following code. So, first calculate downloaded image size and than make image view according to that.
UIImage *Yourimage = [UIImage imageNamed:#"image.png"];
CGFloat width = Yourimage.size.width;
CGFloat height = Yourimage.size.height;
Hope, this will help you..
UIImage *oldimage = [UIImage imageWithContentsOfFile:imagePath]; // or you can set from url with NSURL
CGSize imgSize = [oldimage size];
imgview.frame = CGRectMake(10, 10, imgSize.width,imgSize.height);
[imgview setImage:oldimage];
100% working ....
To solve this problem, we need to take care of the device's display resolution..
For example you have an image of resolution 326ppi which is same as of iPhone4, iPhone4S and iPod 4th Gen. So you can simply use solutions suggested by #Nit and #Peko. But for other devices(or for image with different resolution on these devices) you will need to apply maths to calculate size for better display.
Now suppose you have 260ppi(with dimensions W x H) image and you wish to display it on iPhone4S, so as the information contained in it per inches is less than the display resolution of iPhone so we will need to resize it by reducing image size by 326/260 factor. so now the size for imageView that you will use is
imageViewWidth = W*(260/326);
imageViewHeight = H*(260/326);
In general:
resizeFactor = imageResolution/deviceDisplayResolution;
imageViewWidth = W*resizeFactor;
imageViewHeight = H*resizeFactor;
Here I am considering when we set an image in imageView and resize it, it does not removes or adds pixels from image,
Let the UIImageView do the work by utilizing the contentMode property to do your image resizing for you.
You probably want to be displaying your UIImageView with a static sizing (the "frame" property) that represents the maximum size of the image you want to display, and allowing the images to resize within that frame relative to their own particular size requirements (overall size, aspect ratio, etc.). You can let the UIImageView do the heavy lifting for you of dealing with different sized images by mastering the contentMode property. It has many different settings, one of which is UIViewContentModeScaleAspectFit, which will downsize your image as necessary to fit within the UIImageView, which if the image is smaller, it will simply display centered. You can play with the setting to get the results you want.
Note that with this approach, there is nothing special you need to do to deal with scaling issues associated with a Retina display.
As per the requirement you stated in the question body, I believe you need not change UIImageView size.
Image can represent fully without any blur using this line of code:
imageView.contentMode = UIViewContentModeScaleAspectFit;

Loading images on UIScroll from documents directory

I have different images for portrait and landscape, I fetch the images from the Document directory, their is a total of 62 images. 31 Landscape images having 1015x745 dimensions and 31 Portrait having 751x1024 dimensions. All the images loading on the simulator but when i run the same code within the device the application crash. It load either only the portrait on landscape images.
int porWidth = 768, lanWidth = 1024;
int i=0;
for (CatalogIndividuals *cat in self.array)
{
UIImageView *imageView1 = [[[UIImageView alloc] initWithFrame:CGRectMake(porWidth*i +5, 0, 757, 964)] autorelease];
imageView1.tag = porImage+i;
NSString *fullPath =[self.documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",cat.portraitImage]];
imageView1.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:[fullPath stringByReplacingOccurrencesOfString:#"\\" withString:#"/"]]];
imageView1.contentMode = UIViewContentModeScaleAspectFit;
UIImageView *imageView2 = [[[UIImageView alloc] initWithFrame:CGRectMake(lanWidth*i +5, 0, 1015, 620)] autorelease];
imageView2.tag = lanImage+i;
NSString *tempPath = [self.documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",cat.landscapImage]];
NSString *str = [tempPath stringByReplacingOccurrencesOfString:#"\\" withString:#"/"];
NSLog(#"imageView1 fullPath = %#",str);
imageView2.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:str]];}
I think there is some memory leak problem. please help if anybody has any solution.
That's about 350MB worth of images. You don't have a memory leak, you're just using far too much memory. This is a mobile device, not a desktop computer, the resources available to you are limited.
You shouldn't be loading all the images at once, you should be loading them dynamically as you scroll through the content. Take a look at the sample code Apple provides for UIScrollView to see how you can use tiling to achieve this.

Scaling issue in saving UIImage as NSData

I would like to save some image as nsdata into a plist and retrieve it later.
But I got a problem.
The problem is, if the UIImage with a scale of 2.0, when I load it again later with
[UIImage imageWithData:]
the image show 2x size
What I want is to like the behaviour of
[UIImage imageNamed:]
which will load according to the screen scale.
How can I do it?
I finally solve it by this code:
UIImage *image = [UIImage imageWithData:imageData];
if (isRetinaDisplay) {
image = [UIImage imageWithCGImage:[image CGImage] scale:2.0f orientation:UIImageOrientationUp];
}
You could take into account the possibility that the screen is Retina like so:
CGFloat screenScale = [UIScreen mainScreen].scale;
UIImage *image = [UIImage imageWithData:data scale:screenScale];
This code covers both cases (Retina / non-Retina) in one line.
Since iOS 6 you can also use
+ (UIImage *)imageWithData:(NSData *)data scale:(CGFloat)scale NS_AVAILABLE_IOS(6_0);
The scale property is read-only, but what you can do is subclass UIImageView to make it writable (or make it automatic according to what device it's running on).
// ImageView.h
#interface ImageView : UIImageView
// ImageView.m
CGFloat scaleProperty = 1.0;
#implementation ImageView
- (void)setScale:(CGFloat)scale
{
scaleProperty = scale;
}
- (CGFloat)scale
{
return scaleProperty;
}
#end