CGContext转换,提取旋转的矩形

我的意图是写一个函数,可以提取一个更大的图像旋转的矩形部分。 该旋转矩形部分用中心点(从0,0到全图像宽度/高度)的大小和旋转angular度来描述。

我担心我不了解CGContexts。 我知道,旋转后,我的坐标空间旋转。

如果angular度为0,则此function始终有效,如果angular度较小,此function显示正确。 但是,随着angular度的增加,一切都被错误地抵消了。

我正在计算类似于图像变换的仿射变换来计算左上angular,以避免任何不准确。 我也尝试了通过应用图像变换来进一步改变左上angular,以及图像变换的逆(就像一个随机的想法)。

这种方法会起作用吗? 我是否错过了某处的空间转换?

注意:通过绘制完整的图像,然后在正确的位置以正确的大小和旋转画出一个黑色的矩形,非常容易使图像区域变黑。 鉴于此,我知道我的投入是正确的。

可视化:

这代表完整的形象,我正在尝试示例旋转矩形: 这代表完整的图像,我试图采样旋转矩形

该图像表示此function的所需输出: 该图像表示此功能的所需输出

- (UIImage*) croppedImage:(UIImage*) image center:(CGPoint) rotationCenter size:(CGSize) size rotation:(CGFloat) rotation { CGFloat fullWidth = image.size.width; CGFloat fullHeight = image.size.height; CGRect imageRect = CGRectMake(0, 0, fullWidth, fullHeight); //must convert UI space to CG space, in this case that just means adjusting the y coordinate rotationCenter.y = fullHeight - rotationCenter.y; CGFloat width = size.width; CGFloat height = size.height; int flags = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast; CGContextRef btx = CGBitmapContextCreate(NULL, width, height, 8, 0, CGColorSpaceCreateDeviceRGB(), flags); CGContextSetAllowsAntialiasing(btx, YES); CGContextSetShouldAntialias(btx, YES); //use a transformation to rotate at the center of the request area CGAffineTransform imageTransform = CGAffineTransformIdentity; imageTransform = CGAffineTransformTranslate(imageTransform, rotationCenter.x, rotationCenter.y); imageTransform = CGAffineTransformRotate(imageTransform, rotation); imageTransform = CGAffineTransformTranslate(imageTransform, -rotationCenter.x, -rotationCenter.y); //use a transformation to determine the top-left coordinate of the rect CGAffineTransform ptTransform = CGAffineTransformIdentity; ptTransform = CGAffineTransformTranslate(ptTransform, rotationCenter.x, rotationCenter.y); ptTransform = CGAffineTransformRotate(ptTransform, rotation); ptTransform = CGAffineTransformTranslate(ptTransform, -width/2.0, -height/2.0); //this gets me the position of the top-left corner of the image no matter the rotation CGPoint topleft = CGPointApplyAffineTransform(CGPointZero, ptTransform); CGContextConcatCTM(btx, imageTransform); //move the image away from the origin, to align origin with where i want my image sampled from CGContextTranslateCTM(btx, -topleft.x, -topleft.y); //Close... but wrong CGContextDrawImage(btx, imageRect, image.CGImage); CGImageRef img = CGBitmapContextCreateImage(btx); UIImage* uiimage = [UIImage imageWithCGImage:img scale:image.scale orientation:image.imageOrientation]; CGContextRelease(btx); CGImageRelease(img); return uiimage; } 

我相信你所描述的是这样的事情:

在这里输入图像说明

这是一个实际运行的iOS应用程序,所以你可以看到我已经做了什么:在第一张图片中,我用蓝色绘制了我想要捕获的矩形,并将结果显示在图像视图中; 在第二张照片中,我捕获了它,并在图像视图中显示结果。

正如您仔细观察第二张图像的边缘所看到的,我们已经精确地捕获了蓝色矩形内容。

那么现在我想你想知道我是怎么做到的? 蓝色矩形是使用三条信息绘制的:矩形topLeft ,矩形size和旋转rot 。 为了简化事情,我没有理会你对“中心”的谈话。 我已经左上angular旋转。

然后通过创build尺寸size的graphics上下文来捕获第二个图像,将其旋转为负面的rot ,并在topLeft的负面上绘制完整的原始图像。 实际的绘图部分只是两行代码(对不起,我现在写在Swift中思考,但我相信你可以翻译):

 CGContextRotateCTM(context, -rot) im.drawAtPoint(CGPointMake(-topLeft.x, -topLeft.y)) 

所以我想我的答案最终是:这是非常容易的,正如你所期望的那样工作,如果你将转换原来的描述你想做什么,以便有一个topLeft而不是一个中心。