简体   繁体   English

如何旋转CGRect或CGImageCreateWithImageInRect?

[英]How to rotate a CGRect or CGImageCreateWithImageInRect?

To describe my project: 描述我的项目:

I have a rectangle UIImageView frame floating over a white layer. 我有一个矩形的UIImageView框架,漂浮在白色层上。 Inside the UIImageView, I'm successfully creating the illusion that it is showing a portion of a background image behind the white layer. 在UIImageView内,我成功创建了一种幻觉,即它在白色层后面显示了背景图像的一部分。 You can drag the rectangle around, and it will "redraw" the image so that you can peer into what is behind the white. 您可以在周围拖动矩形,它将“重绘”图像,以便可以窥视到白色后面。 Its basically this code: 它基本上是这样的代码:

//whenever the frame is moved, updated the CGRect frameRect and run this:

self.newCroppedImage = CGImageCreateWithImageInRect([bgImage.image CGImage], frameRect);
 frame.image = [UIImage imageWithCGImage:self.newCroppedImage];

Anyhow, I also have a rotation gesture recognizer that allows the user to rotate the frame (and consequentially rotates the image). 无论如何,我还有一个旋转手势识别器,它允许用户旋转框架(并因此旋转图像)。 This is because the CGRect sent to the CGImageCreateWithImageInRect is still oriented at its original rotation. 这是因为发送到CGImageCreateWithImageInRect的CGRect仍以其原始旋转为方向。 This breaks the illusion that you're looking through a window because the image you see is rotated when only the frame should appear that way. 这打破了您正在透过窗户看的错觉,因为当仅以这种方式出现帧时,您看到的图像会旋转。

So ideally, I need to take the rotation of my frame and apply it to the image created from my bgImage. 因此,理想情况下,我需要旋转框架并将其应用于从bgImage创建的图像。 Does anyone have any clues or ideas on how I could apply this? 有人对我如何应用它有任何线索或想法吗?

I suggest you take a different approach. 我建议您采用其他方法。 Don't constantly create new images to put in your UIImageView . 不要不断创建新图像以放入UIImageView Instead, set up your view hierarchy like this: 相反,应按如下所示设置视图层次结构:

White view
    "Hole" view (just a regular UIView)
        Image view

That is, the white view has the hole view as a subview. 即,白色视图将孔视图作为子视图。 The hole view has the UIImageView as its subview. 孔视图将UIImageView作为其子视图。

The hole view must have its clipsToBounds property set to YES (you can set it with code or in your nib). 孔视图必须将其clipsToBounds属性设置为YES(可以使用代码或在笔尖中进行设置)。

The image view should have its size set to the size of its image. 图像视图的大小应设置为其图像的大小。 This will of course be larger than the size of the hole view. 当然,这将大于孔视图的大小。

And this is very very important: the image view's center must be set to the hole view's center. 这非常重要:图像视图的中心必须设置为孔视图的中心。

Here's the code I used in my test project to set things up. 这是我在测试项目中用来设置代码的代码。 The white view is self.view . 白色视图是self.view I start with the hole centered in the white view, and I set the image view's center to the hole view's center. 我从以白色视图为中心的孔开始,然后将图像视图的中心设置为孔视图的中心。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:YES];

    CGRect bounds = self.view.bounds;
    self.holeView.center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
    self.holeView.clipsToBounds = YES;

    bounds = self.holeView.bounds;
    self.imageView.center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
    self.imageView.bounds = (CGRect){ CGPointZero, self.imageView.image.size };

}

I also set the image view's size to the size of its image. 我还将图像视图的大小设置为其图像的大小。 You might want to set it to the size of the white view. 您可能需要将其设置为白色视图的大小。

To pan and rotate the hole, I'm going to set holeView.transform . 为了平移和旋转孔,我将设置holeView.transform I'm not going to change holeView.frame or holeView.center . 我不会更改holeView.frameholeView.center I have two instance variables, _holeOffset and _holeRotation , that I use to compute the transform. 我有两个实例变量_holeOffset_holeRotation ,用于计算转换。 The trick to making it seem like a hole through the white view, revealing the image view, is to apply the inverse transform to the image view, undoing the effects of the hole view's transform: 使它看起来像是穿过白色视图的洞,从而揭示图像视图的技巧是将变换应用于图像视图,以消除孔视图的变换的影响:

- (void)updateTransforms {
    CGAffineTransform holeTransform = CGAffineTransformIdentity;
    holeTransform = CGAffineTransformTranslate(holeTransform, _holeOffset.x, _holeOffset.y);
    holeTransform = CGAffineTransformRotate(holeTransform, _holeRotation);
    self.holeView.transform = holeTransform;
    self.imageView.transform = CGAffineTransformInvert(holeTransform);
}

This trick of using the inverse transform on the subview only works if the center of the subview is at the center of its superview. 仅当子视图的中心在其父视图的中心时,才可以在子视图上使用逆变换的技巧。 (Technically the anchor points have to line up, but by default the anchor point of a view is its center.) (从技术上讲,锚点必须对齐,但是默认情况下,视图的锚点是其中心。)

I put a UIPanGestureRecognizer on holeView . 我将UIPanGestureRecognizer放在holeView I configured it to send panGesture: to my view controller: 我将其配置为将panGesture:发送到我的视图控制器:

- (IBAction)panGesture:(UIPanGestureRecognizer *)sender {
    CGPoint offset = [sender translationInView:self.view];
    [sender setTranslation:CGPointZero inView:self.view];
    _holeOffset.x += offset.x;
    _holeOffset.y += offset.y;
    [self updateTransforms];
}

I also put a UIRotationGestureRecognizer on holeView . 我还把UIRotationGestureRecognizer放在holeView I configured it to send rotationGesture: to my view controller: 我将其配置为将rotationGesture:发送到我的视图控制器:

- (IBAction)rotationGesture:(UIRotationGestureRecognizer *)sender {
    _holeRotation += sender.rotation;
    sender.rotation = 0;
    [self updateTransforms];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM