如何旋转CGRect或CGImageCreateWithImageInRect? [英] How to rotate a CGRect or CGImageCreateWithImageInRect?

查看:195
本文介绍了如何旋转CGRect或CGImageCreateWithImageInRect?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

描述我的项目:



我有一个漂浮在白色图层上的矩形UIImageView框架。在UIImageView内部,我成功地创建了一个错觉,它在白色层后面显示了一部分背景图像。您可以拖动矩形,它将重绘图像,以便您可以查看白色背后的内容。基本上这个代码:

  //每当移动框架时,更新CGRect frameRect并运行:

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

无论如何,我还有一个旋转手势识别器,允许用户旋转框架(并因此旋转图片)。这是因为发送到CGImageCreateWithImageInRect的CGRect仍然以其原始旋转为导向。这打破了你透过窗户看到的错觉,因为你看到的图像只有框架出现时就会旋转。



理想情况下,我需要采取我的框架旋转并将其应用于从我的bgImage创建的图像。有没有人对我如何应用这个有任何线索或想法?

解决方案

我建议你采取不同的方法。不要经常创建新图像以放入 UIImageView 。相反,设置您的视图层次结构如下:

 白色视图
洞视图(只是常规UIView)
图片查看

也就是说,白色视图将孔视图作为子视图。孔视图将 UIImageView 作为其子视图。



孔视图必须具有 clipsToBounds 属性设置为YES(您可以使用代码或在您的笔尖中设置它)。



图像视图的大小应设置为它的形象大小。这当然会大于孔视图的大小。



这非常重要:图像视图的中心必须设置为孔视图的中心。 / p>

这是我在测试项目中用来设置的代码。白色视图是 self.view 。我从白色视图中心的孔开始,然后将图像视图的中心设置为孔视图的中心。

   - ( void)viewWillAppear:(BOOL)动画
{
[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};

}

我还将图片视图的大小设置为其大小图片。您可能希望将其设置为白色视图的大小。



要平移和旋转孔,我将设置 holeView。变换。我不会改变 holeView.frame holeView.center 。我有两个实例变量, _holeOffset _holeRotation ,我用来计算变换。让它看起来像穿过白色视图的洞,揭示图像视图的技巧是将变换应用于图像视图,撤消孔视图变换的效果:

   - (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);
}

这个在子视图上使用逆变换的技巧仅适用于子视图是其超级视图的中心。 (从技术上讲,锚点必须排成一行,但默认情况下,视图的锚点是它的中心。)



我放了一个 UIPanGestureRecognizer on holeView 。我将其配置为将 panGesture:发送到我的视图控制器:

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

我还放了 UIRotationGestureRecognizer on holeView 。我将其配置为将 rotationGesture:发送到我的视图控制器:

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


To describe my project:

I have a rectangle UIImageView frame floating over a white layer. Inside the UIImageView, I'm successfully creating the illusion that it is showing a portion of a background image behind the white layer. 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. 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. 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. 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.

The hole view must have its clipsToBounds property set to YES (you can set it with code or in your nib).

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. 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. I'm not going to change holeView.frame or holeView.center. I have two instance variables, _holeOffset and _holeRotation, that I use to compute the transform. 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. I configured it to send panGesture: to my view controller:

- (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. I configured it to send rotationGesture: to my view controller:

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

这篇关于如何旋转CGRect或CGImageCreateWithImageInRect?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆