【问题标题】:iOS rotate image inside canvas with CoreGraphicsiOS使用CoreGraphics在画布内旋转图像
【发布时间】:2016-03-05 22:08:39
【问题描述】:

我正在尝试旋转放置在 rect 内且仅覆盖其中一部分的图像。

我已经找到了这个解决方案,但无法旋转图像:

override func drawRect(rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()

    // drawing some texts and lines

    // rotate myImage by 'angle'
    CGContextSaveGState(context)

    CGContextTranslateCTM(context, imageOffset.x, imageOffset.y)
    CGContextRotateCTM(context, angle)
    CGContextTranslateCTM(context, -imageOffset.x, -imageOffset.y)
    myImage?.drawInRect(CGRect(x: imageOffset.x, y: imageOffset.y, width: imageSize.width, height: imageSize.height))

    CGContextRestoreGState(context)

    // draw other stuff
}

那么,如何正确地做呢?

【问题讨论】:

    标签: ios image rotation core-graphics image-rotation


    【解决方案1】:

    您正在创建图像上下文,将图像绘制到其中,然后结束上下文而不输出图像。因此,您将永远看不到输出。

    您需要 UIGraphicsGetImageFromCurrentImageContext() 将旋转后的图像从上下文中取出,然后在视图的上下文中重新绘制它。

    这样的事情应该可以解决问题:

    /// returns the transform equivalent of rotating a rect around its center
    private func rotateTransformRectAroundCenter(rect:CGRect, angle:CGFloat) -> CGAffineTransform {
        let t = CGAffineTransformConcat(
            CGAffineTransformMakeTranslation(-rect.origin.x-rect.size.width*0.5, -rect.origin.y-rect.size.height*0.5),
            CGAffineTransformMakeRotation(angle)
        )
        return CGAffineTransformConcat(t, CGAffineTransformMakeTranslation(rect.size.width*0.5, rect.size.height*0.5))
    }
    
    override func drawRect(rect: CGRect) {
    
        // get current context
        let ctx = UIGraphicsGetCurrentContext()
    
        // the rect to draw the image in
        let rect = CGRect(x: 50, y: 50, width: 300, height: 300)
    
        // angle to rotate image by
        let angle = CGFloat(M_PI*0.25)
    
        // the image bounds
        let imgRect = CGRect(origin: CGPointZero, size: img.size)
    
        // transform of rotating image
        let imgRotate = rotateTransformRectAroundCenter(imgRect, angle: angle)
    
        // rotated image frame
        let rotatedImgFrame = CGRectApplyAffineTransform(imgRect, imgRotate)
    
        // transform of rotating image context
        let rotateContext = rotateTransformRectAroundCenter(rotatedImgFrame, angle: angle)
    
    
        // begin image context
        UIGraphicsBeginImageContextWithOptions(rotatedImgFrame.size, false, img.scale)
    
        let imgContext = UIGraphicsGetCurrentContext()
    
        // rotate image context
        CGContextConcatCTM(imgContext, rotateContext)
    
        // draw image in context
        img.drawInRect(CGRect(origin: CGPointZero, size: img.size))
    
        // get output from context
        let output = UIGraphicsGetImageFromCurrentImageContext()
    
        // end context
        UIGraphicsEndImageContext()
    
        // get the rotated rect for the image to be drawn in the main context
        var outputRect = CGRectApplyAffineTransform(rect, rotateTransformRectAroundCenter(rect, angle: angle))
        outputRect.origin = CGPoint(x: outputRect.origin.x+rect.origin.x, y: outputRect.origin.y+rect.origin.y)
    
        // draw image
        output.drawInRect(outputRect)
    }
    

    【讨论】:

    • 我已经像你说的那样更新了有问题的示例,但仍然没有运气。显然,旋转存在问题,因为我必须旋转整个画布而不仅仅是图像区域。
    • 啊,好吧,在那种情况下,你原来的方法是正确的。您应该创建一个新的图像上下文来渲染图像,然后使用UIGraphicsGetImageFromCurrentImageContext() 输出旋转后的图像,然后您可以在视图的上下文中绘制该图像。我已经用一个例子更新了我的答案。
    • 对于这样一个基本的东西,我看起来有很多开销。我设法做到了一点不同(hackish),但它有效。感谢您的解决方案。
    • @BorutTomazin 请记住,您始终可以缓存从图像上下文生成的旋转图像,允许您在不需要新的图像上下文的情况下重新绘制它。但是,是的,我很惊讶自己需要多少代码才能做到这一点!很高兴您找到了解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 2016-03-13
    • 2015-10-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多