使用CGContextDrawImage旋转图像

Mor*_*ess 11 core-graphics cgcontext cgaffinetransform ios cgcontextdrawimage

如何旋转CGContextDrawImage()中心绘制的图像?

drawRect:

CGContextSaveGState(c);

rect = CGRectOffset(rect, -rect.size.width / 2, -rect.size.height / 2);
CGContextRotateCTM(c, angle);
CGContextDrawImage(c, rect, doodad.CGImage);
CGContextRotateCTM(c, -angle);
CGContextTranslateCTM(c, pt.x, pt.y);

prevRect = rect;

CGContextRestoreGState(c);
Run Code Online (Sandbox Code Playgroud)

我在原点绘制图像,然后在中心旋转图像,然后转换到应该绘制的位置.不工作.

Pet*_*sey 40

关于坐标转换的事情- 嗯,要记住的事情之一 - 就是你不是在操纵对象,比如图形编辑器中的Transform命令; 你在操纵空间本身.

想象一下,该装置通过鹅颈臂悬挂在桌子上,并固定在适当的位置.坐标转换使桌面移动(平移),并以一种方式或另一种方式(旋转)转动,甚至挤压和拉伸(缩放).

关于坐标变换要记住的另一件事是变换总是与原点相关.想象一下,您的桌子的一个角落 - 对应于您视角的一角 - 直接位于您的视图最终在屏幕上的角落下方.翻译移动桌子的角落,桌子的其余部分随之滑动,在屏幕下方以某种方式滑动.旋转使桌子绕过那个角落.

还有一件事:转型影响未来,而不是过去.绘制一些东西然后尝试变换它将无法工作,因为你没有变换你绘制的东西,你将变换你要绘制的空间.因此,我们需要移动桌面才能将图像放在正确的位置.

(我提到最后一部分是因为你有几个转换命令会被你的CGContextRestoreGState电话立即恢复.它们之间没有任何图画可供它们影响.)

那么,让我们从未旋转的图像矩形开始.

CGRect imageRect = { pointWhereYouWantTheImageCentered, doodad.size };
Run Code Online (Sandbox Code Playgroud)

现在,CGContextDrawImage取一个矩形,但是,如你所知,它将从该矩形的左下角绘制图像,而不是中心.(因此整个练习.)

所以,这就是你要做的.在这结束时,你将绘制图像不是在上面显示的那一点,而是在零点 - 也就是在桌子的角落.(不是在角落的中心,而是桌面角落的图像角落.)

这将如何运作?这需要一些设置.你将不得不移动你的办公桌.

首先,您需要向上向右移动桌面,直到桌面的原点位于所需的中心点:

CGContextTranslateCTM(context, imageRect.origin.x, imageRect.origin.y);
Run Code Online (Sandbox Code Playgroud)

然后你进行旋转(将桌子转到原点角落):

CGContextRotateCTM(context, angleInRadians);
Run Code Online (Sandbox Code Playgroud)

然后将桌面向下移动并向左移动图像宽度和高度的一半:

CGContextTranslateCTM(context, imageRect.size.width * -0.5, imageRect.size.height * -0.5);
Run Code Online (Sandbox Code Playgroud)

然后,最后,将图像放在桌子的角落.

CGContextDrawImage(context, (CGRect){ CGPointZero, imageRect.size }, [doodad CGImage]);
Run Code Online (Sandbox Code Playgroud)

桌面移动后,该矩形的中心位于屏幕上您希望图像居中的点的正下方,因此图像居中.


ako*_*ruk 6

此功能可以在现有图像上绘制图像,旋转角度以弧度为单位。

斯威夫特 3:

extension UIImage {
    func putImage(image: UIImage, on rect: CGRect, angle: CGFloat = 0.0) -> UIImage{

        let drawRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(drawRect.size, false, 1.0)

        // Start drawing self
        self.draw(in: drawRect)

        // Drawing new image on top
        let context = UIGraphicsGetCurrentContext()!

        // Get the center of new image
        let center = CGPoint(x: rect.midX, y: rect.midY)

        // Set center of image as context action point, so rotation works right
        context.translateBy(x: center.x, y: center.y)
        context.saveGState()

        // Rotate the context
        context.rotate(by: angle)

        // Context origin is image's center. So should draw image on point on origin
        image.draw(in: CGRect(origin: CGPoint(x: -rect.size.width/2, y: -rect.size.height/2), size: rect.size), blendMode: .normal, alpha:
1.0)

        // Go back to context original state.
        context.restoreGState()

        // Get new image
        let newImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        return newImage
    }

}
Run Code Online (Sandbox Code Playgroud)

如果您需要使用大小和颜色创建和清空图像,请使用:

extension UIImage {
    convenience init?(size: CGSize, color: UIColor) {
        let rect = CGRect(origin: .zero, size: size)
        UIGraphicsBeginImageContextWithOptions(rect.size, true, 1.0)
        color.setFill()
        UIRectFill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        guard let cgImage = image?.cgImage else { return nil }
        self.init(cgImage: cgImage)
    }
}
Run Code Online (Sandbox Code Playgroud)