[英]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.