I rotate the image 45 degrees to the left corner, using Image.rotate, but the image disappears beyond the border of the frame. How can I fix this?
im2 = self.image
rot = im2.rotate(45, expand=True, center=(0, 0))
self.image = rot
Originally the image looks like this:
enter image description here
after a 45 degree rotation like this:
enter image description here
Edit: Judging from your new picture, the center=(0, 0) must mean the origin point of the frame, not the image.
To rotate with the top-left of the image fixed, try this:
rot = im2.rotate(45, expand=True, center=(im2.left, im2.top))
This is assuming that the image has properties that tell you its position within the frame.
You are rotating around the top-left corner center=(0, 0), the origin point for this image. Try using the image center (1/2 width, 1/2 height) as your center of rotation.
I have an image that i rotate to face the touchLocation of the user, but because the bounding box of the UIImageView gets larger. This is ruining some collision detection.
My only plan is to code a new bounding box system to get each of the 4 points in a bounding box and rotate that myself, then write check collide code for that.
But before i do that, is there an easy way to do this?
My rotate code:
- (void)ObjectPointAtTouch{
//Get the angle
objectAngle = [self findAngleToPoint:Object :touchLocation];
//Convert to radian, +90 for image alignment
double radian = (90 + objectAngle)/(180 / M_PI);
//Transform by radian
Object.transform = CGAffineTransformMakeRotation(radian);
}
I figured it out, as seen in other tutorials they also resize the scale off the bouncing box to fix this problem. CGAffineTransform scale I think it is.
I have 6 uiimage plates which are placed on the view. Now I am rotating the images 90 degrees on double tap by using the below code:
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI * 0.5);
plate.transform = transform;
For first double tap it rotates 90 degree but when double tap second time it doesn't rotate.
Am i missing something ? Thanks in advance.
AffineTransform keeps the data of the transformation saved. So if you scale/rotate/move the view, the AffineTransform will keep that info.
In order to rotate 90 degree each time, you will have to get the current value and then modify it, or just keep a variable of your current degree and change the variable.
It's because you are already there, you have already rotated those rads. Try by increwsing the rotation value everytime the user taps the image.
I am developing image redraw app. i know the center of one image view which is having scaling property. i.e it can change it frame and center . that to be applied to another view center. when i apply center to newly formed Image view it giving wrong center because of the previous image view is having scaling property. so how can i get exact center to my new image view from previous imageview
Your view or image is
width*height
your center view should always be in position
(width/2,height/2)
whether the image is scaled or not.
Just recalculate your center after the scale if you need the "scaled" center or keep in memory the original center position if you don't.
Pseudocode:
getCenter(w,h){
pos[0]=w/2;
pos[1]=h/2;
return pos;
}
calc(image){
c = getCenter(image.w,image.h);
scaled = image.scale(80); //That is 80% of original
d = getCenter(scaled.w,scaled.h);
if(something) return c;
else return d;
}
Second explanation after discussion (read comments):
Let's assume you have a 640X480 image and you create a view of 320X240 (a quarter of it) and you move THIS view 100px right and 50 pixels down from position (0,0) which is usually top left corner of your image then:
your new center of the VIEW will be as usual in position (160,120) of the VIEW
the original center of the ORIGINAL image will remain in its position (320,240) which casually corresponds to the bottom right corner of your VIEW.
IF you want to know WHERE the original center of the ORIGINAL image DID end up AFTER movement and "cropping" then you just have to know where did you move the VIEW:
100px right becomes (original position - relative movement) (320 - 100) = 220
50px down becomes (original position - relative movement) (240 - 50) = 190
So your ORIGINAL center will be in position (220,190) of the new VIEW.
I have a UIImageView that displays a bigger image. It appears to be centered, but I would like to move that image inside that UIImageView. I looked at the MoveMe sample from Apple, but I couldn't figure out how they do it. It seems that they don't even have an UIImageView for that. Any ideas?
What you need is something like (e.g. showing the 30% by 30% of the top left corner of the original image):
imageView.layer.contentsRect = CGRectMake(0.0, 0.0, 0.3, 0.3);
Description of "contentsRect":
The rectangle, in the unit coordinate space, that defines the portion of the layer’s contents that should be used.
Original Answer has been superseded by CoreAnimation in iOS4.
So as Gold Thumb says: you can do this by accessing the UIView's CALayer. Specifically its contentRect:
From the Apple Docs: The rectangle, in the unit coordinate space, that defines the portion of the layer’s contents that should be used. Animatable.
Do you want to display the image so that it is contained within the UIImageView? In that case just change the contectMode of UIImageView to UIViewContentModeScaleToFill (if aspect ratio is inconsequential) or UIViewContentModeScaleAspectFit (if you want to maintain the aspect ratio)
In IB, this can be done by setting the Mode in Inspector.
In code, it can be done as
yourImageView.contentMode = UIViewContentModeScaleToFill;
In case you want to display the large image as is inside a UIImageView, the best and easiest way to do this would be to have the image view inside a UIScrollView. That ways you will be able to zoom in and out in the image and also move it around.
Hope that helps.
It doesn't sound like the MoveMe sample does anything like what you want. The PlacardView in it is the same size as the image used. The only size change done to it is a view transform, which doesn't effect the viewport of the image. As I understand it, you have a large picture, and want to show a small viewport into it. There isn't a simple class method to do this, but there is a function that you can use to get the desired results: CGImageCreateWithImageInRect(CGImageRef, CGRect) will help you out.
Here's a short example using it:
CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect);
[UIImageView setImage:[UIImage imageWithCGImage:imageRef]];
CGImageRelease(imageRef);
Thanks a lot. I have found a pretty simple solution that looks like this:
CGRect frameRect = myImage.frame;
CGPoint rectPoint = frameRect.origin;
CGFloat newXPos = rectPoint.x - 0.5f;
myImage.frame = CGRectMake(newXPos, 0.0f, myImage.frame.size.width, myImage.frame.size.height);
I just move the frame around. It happens that portions of that frame go out of the iPhone's view port, but I hope that this won't matter much. There is a mask over it, so it doesn't look weird. The user doesn't totice how it's done.
You can accomplish the same by:
UIImageView *imgVw=[[UIImageView alloc]initwithFrame:CGRectMake(x,y,height,width)];
imgVw.image=[UIImage imageNamed:#""];
[self.view addSubView imgVw];
imgVw.contentMode = UIViewContentModeScaleToFill;
You can use NSLayoutConstraint to set the position of UIImageView , it can be relative to other elements or with respect to the frame.
Here's an example snippet:
let logo = UIImage(imageLiteralResourceName: "img")
let logoImage = UIImageView(image: logo)
logoImage.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(logoImage)
NSLayoutConstraint.activate([logoImage.topAnchor.constraint(equalTo: view.topAnchor,constant: 30),
logoImage.centerXAnchor.constraint(equalTo: view.centerXAnchor),logoImage.widthAnchor.constraint(equalToConstant: 100),logoImage.heightAnchor.constraint(equalToConstant: 100)
])
This way you can also resize the image easily. The constant parameter represents, how far should a certain anchor be positioned relative to the specified anchor.
Consider this,
logoImage.topAnchor.constraint(equalTo: view.topAnchor,constant: 30)
The above line is setting the top anchor of the instance logoImage to be 30 (constant) below the parent view. A negative value would mean opposite direction.