I would like to truncate one end of a UIImageView by changing the size of the frame dynamically. Of course, if it autoresizes it won't look 'truncated', but will look shrunk. The former is the effect I would like, the latter not.
So far I've set up the UIImageView in IB and then hooked it up programmatically using IBOutlet. I then placed this in ViewDidLoad, but still get the autoresizing:
[self.stringImageView setAutoresizingMask:UIViewAutoresizingNone];
self.stringImageView.frame = CGRectMake(9.0f, 508.0f, 500.0f, 26.0f);
Any ideas how I can clip my UIImageView instead of having it resize?
EDIT 1
It should also be noted that in IB I have deselected Clip Subviews and Autoresize Subviews.
Use : stringImageView.contentMode = UIViewContentModeCenter; so the image you add to the UIImageView always keeps the same size and the same position in your view.
You need to clip the UIImage object first according to imageview's frame and then set it as image for image view. See also Cropping an UIImage
#implementation UIImage (Resize)
// Returns a copy of this image that is cropped to the given bounds.
// The bounds will be adjusted using CGRectIntegral.
// This method ignores the image's imageOrientation setting.
- (UIImage *)croppedImage:(CGRect)bounds {
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], bounds);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return croppedImage;
}
In Interface Builder set Mode in the View Tab to "Top" or whatever it should be.
Another more efficient way to go if you only wish to make part of the image visible,
or for example animate its appearance,
is to set the content mode of the UIImageView to UIViewContentModeCenter (or any other alignment) and include it in a UIScrollView.
You will only need to change the frame of the scroll view and your image will be visually cropped without you having to create the cropped image (which would be a very high price if it is for animation purpose).
Related
I'm writing code to use a custom image as the background for a UIView.
The app runs in portrait only. Prior to the 4" retina screen, I used fixed size, hand-drawn png as the background image (card.png below). I had code like this:
UIView* frontView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
frontView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
UIImage* cardImage = [UIImage imageNamed:#"card.png"];
UIImageView* im = [[UIImageView alloc] initWithImage:cardImage];
im.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
[frontView addSubview:im];
// frontView has a bunch of stuff added...
As you'd expect, when I run this on an iPhone 5, everything can be dynamically sized and positioned, except for the hand drawn png, card.png. So that background image isn't using the full height that is available...
So what (I think) I want to do, is something like this...
UIImage* cardImage = [[UIImage imageNamed:#"card_resizable.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(72, 0, 60, 0)];
I've redrawn card.png as card_resizable.png - it's 140 pixels in height, there's an 8 pixel chunk in the middle, which I want to tile, so the top inset is 72 pixels tall and the bottom inset is 60 pixels tall.
What's the next step?
Should I create the UIImageView with the dynamic size of frontView?
How do I make the resizable image, resize?
The few things that I've tried... none of them have resulted in tiling the resizable image.
Cheers,
Gavin
Update:
I was incorrectly setting the pixel values for UIEdgeInsetsMake(72, 0, 60, 0)
These values are based on the #2x image. When changed to UIEdgeInsetsMake(36, 0, 30, 0) - I get the correct, vertical resizing.
As Mike pointed out, I needed to set the size of the UIImageView to the parent, and correctly set it's autoresizingMask:
im.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
I know have the UIImageView sized dynamically sized, correctly, to fill its parent view - frontView (I've given it a green background to check visually on both 3.5" screen and 4" screen.
The resizable image, cardImage, is also resizing, correctly, in the vertical plane.
Once you've passed the stretchable image to a UIImageView you just resize that image view to whatever height you need.
In your case, you probably want to make the image view fill its parent by doing this:
im.frame = frontView.bounds;
im.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[frontView addSubview:im];
We make im fill the frontView and tell it to automatically increase its width/height when its parent (frontView) changes size. This should do what you want.
Can you try with stretchableImage
UIImage *image = [UIImage imageNamed:#"card_resizable.png"];
UIImage* cardImage = [image stretchableImageWithLeftCapWidth:0.0f
topCapHeight:70.0f];
Take a look at UIView contentMode property. it should give you some sense about how the UIImageView render the image inside, whenever it change it's size.
I have this chunk of code which is placed in accelerometer: didAccelerate which changes the cropping of an image. Basically as you tilt an iPad an image gets truncated (not resized) which is exactly the effect I'm looking for. Note: self.xPos is effected by the position of accelerometer.x.
UIImage *originalStringImage = [UIImage imageNamed:#"string.png"];
CGImageRef imageRef = CGImageCreateWithImageInRect([originalStringImage CGImage], CGRectMake(0.0f,0.0f, self.xPos+50.0f, 26.0f));
[self.stringImageView setImage:[UIImage imageWithCGImage:imageRef]];
self.stringImageView.frame = CGRectMake(10.0f, self.stringYPos, self.xPos+50.0f, 26.0f);
Now I would like to do the exact same thing, although as a UIView animation. Something between these UIView animation parameters:
UIImageView *pageStringImageView = [[UIImageView alloc] initWithFrame:CGRectMake(10.0f, placeString, 0.0f, 42.0f)];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelay:2.0];
[UIView setAnimationDuration:3.0];
pageStringImageView.frame = CGRectMake(10.0f, placeString, 900.0f, 42.0f);
UIImage *originalStringImage = [UIImage imageNamed:#"string.png"];
CGImageRef imageRef = CGImageCreateWithImageInRect([originalStringImage CGImage], CGRectMake(10.0f,placeString, pageStringImageView.frame.origin.x, 42.0f));
[pageStringImageView setImage:[UIImage imageWithCGImage:imageRef]];
[UIView commitAnimations];
But the above doesn't work it all. In fact it doesn't even show the image. I believe the main difficulty here is changing the size of the image dynamically while the UIView animation is running.
Any suggestions or questions?
This should be fairly simple to do if you use the scaling properties of your UIImageView (the .contentMode property).
Views - including image views - can display there content in a number of ways. The default for an image view is to scale the content, so when you change the frame/bounds of the image it shrinks / expands as appropriate.
So if you were to use a standard UIView animation block to adjust the frame of a UIImageView it would animate the image scaling or shrinking. But if you change the image view's .contentMode property if you change the frame you can have it crop instead.
For example, UIViewContentModeLeft will align the content with the left hand side of the view, so if you adjust the width of the view it will be 'cropped' from the right side. Check the UIView documentation to see all the values you can have for contentMode. So basically, just animate your view's frame changing, but set the contentMode appropriately to give you the desired cropping effect. You may need to make sure your view is set to clip to bounds, although I have a feeling image views do this by default.
I am new to iphone development and making an application which chooses an image from existing album. After choosing the image I want to put another View on it, or another icon(acne).
Can anyone tell me how to put another image on existing image by code????
Basically if you want to overlay two views/images you can just do it like this:
[self.view addSubview:imageview1];
[self.view addSubview:imageview2];
imageview2 lays on imageview1, because you added it later.
You want to place UIImageView or UIView on the image ?
First you need to create the ImageView with the frame of your choosen image and create another ImageView in the same way as you created first ImageView and add second ImageView to your previous ImageView. if your second ImageView size is equal to the size of first ImageView, you would not be able to see your first ImageView, because it will overlap..
If you want to add a watermark on your image try this code:
UIGraphicsBeginImageContext(CGSizeMake(320, 480));
// This is where we resize captured image
[(UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage] drawInRect:CGRectMake(0, 0, 320, 480)];
// And add the watermark on top of it
[[UIImage imageNamed:#"Watermark.png"] drawAtPoint:CGPointMake(0, 0) blendMode:kCGBlendModeNormal alpha:WATERMARK_ALPHA];
// Save the results directly to the image view property
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
In iPhone application I want to generate a image of UIScrollView whose content size is near about 600*41000. If I use current graphic image context to capture the scroll view layer, then it only captures the visible part of the scroll view not the whole layer of that scroll view.
I am using the below code:
{
UIGraphicsBeginImageContext(CGSizeMake(600, 4100));
[scrollView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *img = [[UIImageView alloc]initWithFrame:CGRectMake(00, 100, 710, 4100)];
img.image = viewImage;
[anotherScrollView addSubview:img];
}
Try to generate image not from UIScrollView but from its content view. When you add some views to UIScrollView with something like addSubview: they become scroll's content ones. Of course, UIScrollView can have more than one content view (just as any UIView can have more than one subview) and this case it will be more difficult to render its layer. But in case of only one subview (content view) you can use something like (contentView here is just some view, added to UIScrollView before):
[contentView.layer renderInContext:UIGraphicsGetCurrentContext()];
or:
[[[[scrollView subviews] lastObject] layer] renderInContext:UIGraphicsGetCurrentContext()];
When you want to use more than one view, it will be easier (I think) to add one more "root" view and add others as that view's subviews: so you can also use the code above.
I'd like to show an image in an iPhone app, but the image I'm using is too big.
I'd like to scale it to fit the iPhone screen, I can't find any class to handle it.
UIImageView* view = [[UIImageView alloc] initWithImage: [UIImage imageNamed: #"your_image.png"]];
view.frame = CGRectMake(0, 0, width, height);
To get the frame of the iPhone screen you can use
CGRect frame = [[UIScreen mainScreen] bounds];
In Interface Builder, select your UIImageView. From the Tools menu, select "Attribute Inspector". In the Image View Attributes palette, select "Scale to Fill" from the Mode popup. That should scale your image to fit.
My ImageView was set in IB, and I would need to show multiple images, so set the image of imageView, instead of creating ImageView for individual image.
After I set the image view frame size, I am still see the same result, the image was too big, so that only part of the image was displayed on the screen.