簡體   English   中英

UIGraphicsGetImageFromCurrentContext並保留寬高比

[英]UIGraphicsGetImageFromCurrentContext and preserve aspect ratio

我正在嘗試實現UIImageView子類,該子類將允許用戶使用其手指在圖像視圖中進行繪制。 我的UIImageView的contentMode設置為Aspect Fill 我注意到執行繪圖代碼並將結果圖像從圖形上下文中提取時,它正以“ Scale to Fill類型的格式進行縮放,這不是我想要的。 我想知道是否有人知道如何實現提取此圖像並保持圖像的縱橫比。

class DrawImageView : UIImageView {

    var lastTouchPoint = CGPoint.zero
    var isSwiping = false

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        isSwiping = false 
        if let touchPoint = touches.first {
            lastTouchPoint = touchPoint.location(in: self)
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        isSwiping = true

        if let touchPoint = touches.first {
            let currentPoint = touchPoint.location(in: self)
            UIGraphicsBeginImageContext(frame.size)

            image?.draw(in: CGRect(x:0, y:0, width:frame.size.width, height:frame.size.height))

            if let context = UIGraphicsGetCurrentContext() {
                context.move(to: lastTouchPoint)
                context.addLine(to: currentPoint)
                context.setLineCap(CGLineCap.round)
                context.setLineWidth(9.0)
                context.setStrokeColor(red: 0/255.0, green: 0/255.0, blue: 0/255.0, alpha: 1.0)
                context.strokePath()
                image = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                lastTouchPoint = currentPoint
            }
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if(!isSwiping) {

            UIGraphicsBeginImageContext(frame.size)
            image?.draw(in: CGRect(x:0, y:0, width:frame.size.width, height:frame.size.height))


            if let context = UIGraphicsGetCurrentContext() {
                context.setLineCap(CGLineCap.round)
                context.setLineWidth(9.0)
                context.setStrokeColor(red: 0/255.0, green: 0/255.0, blue: 0/255.0, alpha: 1.0)
                context.move(to: lastTouchPoint)
                context.addLine(to: lastTouchPoint)
                context.strokePath()
                image = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
            }
        }
    }
}

使用此代碼:

UIGraphicsBeginImageContext(frame.size)
image?.draw(in: CGRect(x:0, y:0, width:frame.size.width, height:frame.size.height))

您說的是“將完整的圖像-不論大小或寬高比-都繪制成寬度x高度尺寸的矩形”。 因此,如果image的“原始”尺寸為300 x 200,而您的frame為200 x 200,則將在此處繪制圖像。

為了避免這種情況,您需要計算要吸收的適當矩形。 使用這些尺寸,您要進行以下操作(用於寬高比填充):

image?.draw(in: CGRect(x:-50, y:0, width:frame.size.width + 50, height:frame.size.height))

當然,您可以運行快速計算來確定實際數字,而不是硬編碼值。

我最終發現並用於提供寬高比填充rect和寬高比擬合rect的功能如下:

 func getAspectFillFrame(sizeImageView : CGSize, sizeImage: CGSize) -> CGRect {

        let aspect = sizeImage.width / sizeImage.height
        let rect: CGRect

        if sizeImageView.width / aspect > sizeImageView.height {

            let height = sizeImageView.width / aspect

            rect = CGRect(x: 0, y: (sizeImageView.height - height) / 2,
                          width: sizeImageView.width, height: height)

        } else {
            let width = sizeImageView.height * aspect
            rect = CGRect(x: (sizeImageView.width - width) / 2, y: 0,
                          width: width, height: sizeImageView.height)
        }

        return rect

    }

    func getAspectFitFrame(sizeImgView:CGSize, sizeImage:CGSize) -> CGRect {

        let imageSize:CGSize  = sizeImage
        let viewSize:CGSize = sizeImgView

        let hfactor : CGFloat = imageSize.width/viewSize.width
        let vfactor : CGFloat = imageSize.height/viewSize.height

        let factor : CGFloat = max(hfactor, vfactor)

        // Divide the size by the greater of the vertical or horizontal shrinkage factor
        let newWidth : CGFloat = imageSize.width / factor
        let newHeight : CGFloat = imageSize.height / factor

        var x:CGFloat = 0.0
        var y:CGFloat = 0.0
        if newWidth > newHeight{
            y = (sizeImgView.height - newHeight)/2
        }
        if newHeight > newWidth{
            x = (sizeImgView.width - newWidth)/2
        }
        let newRect:CGRect = CGRect(x: x, y: y, width: newWidth, height: newHeight)

        return newRect

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM