I have a photo with size is 320 x 2560, i use a scrollview and imageview to display on iPhone. but i dont know why, if i set the imageview.frame height to 2560, the image is not fully displayed, if i increase the height to 3660, full image is displayed. i am using xcode5 with storyboard
here is the code:
UIImage *img = [UIImage imageNamed:#"photo.jpg"];
[self.imageView setImage:img];
self.imageView.frame = CGRectMake(0, 0, 320, 3660);
//self.imageView.frame = CGRectMake(self.imageView.frame.origin.x, self.imageView.frame.origin.y,img.size.width, img.size.height);
[self.scollView setContentSize:CGSizeMake((self.imageView.frame.size.width), (self.imageView.frame.size.height))];
Related
I am working on application in which the images are coming from server which i have to display in UIImageview which size is of screen size. the problem is some image resolution are very bigger. So, when I use AspectFill it does not appear properly, it is getting shrink and when I use AspectFit it appears in rectangle shape in image view . so is there any way to display image in UIImageView without getting shrink and without getting croped.
Thanks in advance
I think changing contentMode to UIViewContentModeScaleToFill of your imageView should help:
yourImageView.image = yourImage;
yourImageView.contentMode = UIViewContentModeScaleToFill;
CGRect frame = someImageView.frame;
frame.size = yourImage.size;
yourImageView.frame = frame;
Try this
-(UIImage*)resizeImage:(UIImage *)image imageSize:(CGSize)size
{
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0,0,size.width,size.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
//here is the scaled image which has been changed to the size specified
UIGraphicsEndImageContext();
return newImage;
}
And then use new image for your imageView
You can set image using
UIImage * image=[UIImage imageNamed:#"image.png"];
CGSize size=CGSizeMake(50, 63);//set the width and height
UIImage resizedImage= [self resizeImage:image imageSize:size];
Hope it helps.
try :
UIImageView *yourImageView = [[UIImageView alloc] initWithFrame:CGRectMake(x, y, width, height)];
yourImageView.contentMode = UIViewContentModeRedraw;
yourImageView.image = yourImage;
i hope it helps.
I'm using -drawViewHierarchyInRect:afterScreenUpdates: to draw a view into a UIImage, but it seems no matter what I do the results is always a very low resolution, because the image seems to need to be the same size as the original view?
The UIView is the size of the screen (in this case, 375 x 667), and the content scale factor is 2.0f.
But when I use -drawViewHierarchyInRect:afterScreenUpdates: to draw the view onto the image, it is resized (horribly) to this resolution, even though the contents is a much higher resolution.
I'm using UIGraphicsBeginImageContextWithOptions with a scale of 0.0 to create the image, so I assumed it should draw nicely, but no go. How do you draw the view hierarchy and not lose the detail?
Edit:
Here's some example code (from the answer below, which is giving the same result). It's giving me terribly down-scaled results when trying to draw the UIView hierarchy which includes a high res image:
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0);
[self.view drawViewHierarchyInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) afterScreenUpdates:NO];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.frame = self.view.bounds;
[self.view addSubview:imgView];
[self.view bringSubviewToFront:imgView];
This code works perfectly. It takes screenshot of current view and puts it to new created UIImageView. Please check that
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0);
[self.view drawViewHierarchyInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) afterScreenUpdates:NO];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.frame = self.view.bounds;
[self.view addSubview:imgView];
[self.view bringSubviewToFront:imgView];
I would like to add an image to the middle of the UINavigationBar. I could do it easily, but the image that I set is always pixelated no matter what resolution options i use.
I tried these two solutions, but it's still pixeled.
//1.
UIImage *logoImage = [UIImage imageNamed:#"logo.png"];
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:logoImage];
//2.
CGRect myImageRect = CGRectMake(0, 0, 30, 30);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:myImageRect];
[myImage setImage:[UIImage imageNamed:#"logo.png"]];
myImage.contentMode = UIViewContentModeScaleAspectFill;
self.navigationItem.titleView = myImage;
I've tried to play with the image sizes, but the result was always abnormal. Is it any other solution that I could try? Or is there any recommended resolution for the png? I tried 100 x 100 px, 44 x 44 px and 30 x 30 px.
I know this topic has lots of Q&A, I read them all and still couldn't get it going...
I'm trying to stretch an image, while keeping its rounded edges.
This is my image (104x77px):
this is the code I'm using:
UIImage *bg = [UIImage imageNamed:#"btnBg"];
UIEdgeInsets insets = UIEdgeInsetsMake((bg.size.height - 1)/2, (bg.size.width - 1)/2, (bg.size.height - 1)/2, (bg.size.width - 1)/2);
bg = [bg resizableImageWithCapInsets:insets];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 50, 44)];
imgView.image = bg;
UIImageView *imgView2 = [[UIImageView alloc] initWithFrame:CGRectMake(20, 70, 250, 44)];
imgView2.image = bg;
[self.view addSubview:imgView];
[self.view addSubview:imgView2];
and this is the problem:
As you can see each image has different edges.
What am I doing wrong?!
I think what you are looking for is a stretchable image
[[UIImage imageNamed:#"someimage.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:5];
As maddy points out this is deprecated in iOS 5, for those of us poor souls having to support iOS 4.3 this is what we use.
Whenever any scaling is involved, images of two different dimensions can't look quite the same. However you can break your image into three parts: the left corners, the middle section (just the parallel lines), and the right corners.
Now to create image views of different sizes, you'll keep the left and right parts constant, and scale the middle section, which won't look distorted as long as you keep the heights constant.
Note that I have give the height of fitInRect as 77 because that's the original image height. You can change this to, say, 44 but keep the number constant for all image views.
Finally, widthToPreserve HAS to be a minimum of 34 (which means the overall Rect width has to be 68 or more) because that's the width of the rounded edge in the original image.
Of course, you can simply all this by having a smaller image, if your target image view height is 44.
This code works:
-(void)viewDidAppear:(BOOL)animated
{
UIImage *img = [UIImage imageNamed:#"img"];
UIImageView *view1 = [self getImageViewFromImage:img widthToPreserve:34 fitInRect:CGRectMake(20, 20, 100, 77)];
UIImageView *view2 = [self getImageViewFromImage:img widthToPreserve:34 fitInRect:CGRectMake(20, 120, 250, 77)];
[self.view addSubview:view1];
[self.view addSubview:view2];
}
-(UIImageView*)getImageViewFromImage:(UIImage*)image widthToPreserve:(float)width fitInRect:(CGRect)rect
{
CGImageRef left, middle, right;
CGRect leftRect, middleRect, rightRect;
UIImage *leftImage, *middleImage, *rightImage;
UIImageView *leftView, *middleView, *rightView;
// calculate CGRect values for the original image
leftRect = CGRectMake(0, 0, width, image.size.height);
middleRect = CGRectMake(width, 0, image.size.width - 2*width, image.size.height);
rightRect = CGRectMake(image.size.width - width, 0, width, image.size.height);
left = CGImageCreateWithImageInRect([image CGImage], leftRect);
middle = CGImageCreateWithImageInRect([image CGImage], middleRect);
right = CGImageCreateWithImageInRect([image CGImage], rightRect);
leftImage = [UIImage imageWithCGImage:left];
middleImage = [UIImage imageWithCGImage:middle];
rightImage = [UIImage imageWithCGImage:right];
leftView = [[UIImageView alloc] initWithImage:leftImage];
middleView = [[UIImageView alloc] initWithImage:middleImage];
rightView = [[UIImageView alloc] initWithImage:rightImage];
//make your image subviews, with scaling on the middle view
[leftView setFrame:CGRectMake(0, 0, width, rect.size.height)];
[middleView setFrame:CGRectMake(width, 0, rect.size.width - 2*width, rect.size.height)];
[rightView setFrame:CGRectMake(rect.size.width - width, 0, width, rect.size.height)];
//add your 3 subviews into a single image view
UIImageView *imgView = [[UIImageView alloc] initWithFrame:rect];
[imgView addSubview:leftView];
[imgView addSubview:middleView];
[imgView addSubview:rightView];
CGImageRelease(left);
CGImageRelease(middle);
CGImageRelease(right);
return imgView;
}
Screenshot:
You can specify the residing mode for your image. The choices are UIImageResizingModeStretch and UIImageResizingModeTile.
The idea of having a stretchable image is so that you can have a small image file. You should consider using a smaller image to save space in your app bundle. Also, your left and right edge insets don't have to be in the middle. They should be just beyond the curve, which looks to be about 40 points in your image.
Here's the code to use to set the resizing mode:
bg = [bg resizableImageWithCapInsets:insets resizingMode: UIImageResizingModeStretch];
Check this out: Resizable UIImage where outside stretches and inside is kept the same
Basically the opposite of what you want. Hope it helps!
I have an image that can be stretched in the horizontal direction, but need to be tiled vertically (one on top of the other) to fill my view. How could I do this?
I know that an image can be made resizable by using the -(UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets method. So that works great for the horizontal direction but that method cannot be used for the vertical direction it really needs to be tiled, and not stretched in the vertical direction to work.
Now my idea of how this could work is to run a loop that creates a UIImageView with the horizontally stretched image, and simply adjust the frame.origin.y property, then add it as a subview each loop until I've gone past the height of the view. However this seems like an overly complex way of doing this and really not practical when the view need to be resized (on an iPad rotation for example)
Is there a simpler more efficient way of doing this on iOS 6.x?
I used this to tile an image horizontally in a UIImageView:
UIImage *image = [UIImage imageNamed:#"my_image"];
UIImage *tiledImage = [image resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeTile];
UIImageView *imageView = [[UIImageView alloc] initWithImage:tiledImage];
This assumes you set the frame of the UIImageView to a larger size than your image asset. If the height is taller than your image, it will also tile vertically.
Have you considered using UIColor's method colorWithPatternImage: to create a repeating pattern and just pass an image with the correct horizontal width?
Code Example:
// On your desired View Controller
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *patternImage = [UIImage imageNamed:#"repeating_pattern"];
self.view.backgroundColor = [UIColor colorWithPatternImage:patternImage];
// ... do your other stuff here...
}
UIImage *image = [UIImage imageNamed:#"test.png"];
UIImage *resizableImage = [image resizableImageWithCapInsets:UIEdgeInsetsMake(0, image.size.width / 2, 0, image.size.width / 2)];
So I've figured out a solution for this. It is I think a little jacky but it works.
Basically what I've done was to create my stretchable image with the left and right caps specified. And then I initialize a UIImageView with it. I then adjust the frame of the image view to the desired width. This will appropriately resize the image that is contained within it.
Then finally I used a piece of code I found that creates a new image by vertically tiling the adjusted image that is now contained in the image view. Notice how instead of accessing the original UIImage I am using the UIImageView view's image property.
The last thing then is to set the new UIImage as the patterned background colour of the view
Here is the code:
// create a strechable image
UIImage *image = [[UIImage imageNamed:#"progressBackgroundTop#2x.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 60, 0, 60)];
// create the image view that will contain it
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect frame = imageView.frame;
frame.size.width = self.view.bounds.size.width;
imageView.frame = frame;
// create the tiled image
CGSize imageViewSize = imageView.bounds.size;
UIGraphicsBeginImageContext(imageViewSize);
CGContextRef imageContext = UIGraphicsGetCurrentContext();
CGContextDrawTiledImage(imageContext, (CGRect){ CGPointZero, imageViewSize }, imageView.image.CGImage);
UIImage *finishedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.view.backgroundColor = [UIColor colorWithPatternImage:finishedImage];