在 drawRect 中绘制时图像略微模糊 (Swift)
Image blurred slightly when drawing in drawRect (Swift)
我正在 Swift 中构建一个圆形裁剪功能。我几乎一切正常,但是当我保存裁剪后的照片时,它有点模糊:
不确定它在这里是否可见,但在我的 iPhone 上我可以看到差异,轻微模糊。我没有放大超过图像的实际大小。我正在使用最大缩放因子设置为 1.0 的 UIScrollView。作物代码是:
func didTapOk() {
let scale = scrollView.zoomScale
let newSize = CGSize(width: image!.size.width*scale, height: image!.size.height*scale)
let offset = scrollView.contentOffset
UIGraphicsBeginImageContext(CGSize(width: 240, height: 240))
let circlePath = UIBezierPath(ovalInRect: CGRect(x: 0, y: 0, width: 240, height: 240))
circlePath.addClip()
var sharpRect = CGRect(x: -offset.x, y: -offset.y, width: newSize.width, height: newSize.height)
sharpRect = CGRectIntegral(sharpRect)
image?.drawInRect(sharpRect)
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
UIImageWriteToSavedPhotosAlbum(finalImage, nil, nil, nil)
}
我在这里尝试使用CGRectIntegral
来改善结果,但似乎没有任何区别。关于我可以做些什么来改善这一点的任何指示?
发生的事情是您的裁剪图变得模糊,因为它没有考虑屏幕的比例(无论您使用的是 Retina 显示器等)。
使用UIGraphicsBeginImageContextWithOptions(CGSize(width: 240, height: 240), true, 0)
来解释视网膜屏幕。查看 here 以了解有关如何使用此功能的更多详细信息。
我怀疑,虽然上面接受的答案对你有用,但它只是因为屏幕比例与图像比例相同才起作用。
由于您不是从屏幕本身渲染图像(您是从 UIImage
渲染到另一个 UIImage
),屏幕比例应该无关紧要。
您应该在创建上下文时传入图像的比例,如下所示:
UIGraphicsBeginImageContextWithOptions(CGSize(width: 240, height: 240), false, image.scale)
这是 Swift 3 中禁用任何插值的方法。
UIGraphicsBeginImageContextWithOptions(imageSize, false, UIScreen.main.scale)
let context = UIGraphicsGetCurrentContext()
context?.interpolationQuality = CGInterpolationQuality.none
此外,由于这通常用于绘制像素,您可能需要添加:
// Ensure the image is not drawn upside down
context?.saveGState()
context?.translateBy(x: 0.0, y: maxHeight)
context?.scaleBy(x: 1.0, y: -1.0)
// Make the drawing
context?.draw(yourImage, in: CGRect(x: 0, y: 0, width: maxWidth, height: maxHeight))
// Restore the GState of the context
context?.restoreGState()
我正在 Swift 中构建一个圆形裁剪功能。我几乎一切正常,但是当我保存裁剪后的照片时,它有点模糊:
不确定它在这里是否可见,但在我的 iPhone 上我可以看到差异,轻微模糊。我没有放大超过图像的实际大小。我正在使用最大缩放因子设置为 1.0 的 UIScrollView。作物代码是:
func didTapOk() {
let scale = scrollView.zoomScale
let newSize = CGSize(width: image!.size.width*scale, height: image!.size.height*scale)
let offset = scrollView.contentOffset
UIGraphicsBeginImageContext(CGSize(width: 240, height: 240))
let circlePath = UIBezierPath(ovalInRect: CGRect(x: 0, y: 0, width: 240, height: 240))
circlePath.addClip()
var sharpRect = CGRect(x: -offset.x, y: -offset.y, width: newSize.width, height: newSize.height)
sharpRect = CGRectIntegral(sharpRect)
image?.drawInRect(sharpRect)
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
UIImageWriteToSavedPhotosAlbum(finalImage, nil, nil, nil)
}
我在这里尝试使用CGRectIntegral
来改善结果,但似乎没有任何区别。关于我可以做些什么来改善这一点的任何指示?
发生的事情是您的裁剪图变得模糊,因为它没有考虑屏幕的比例(无论您使用的是 Retina 显示器等)。
使用UIGraphicsBeginImageContextWithOptions(CGSize(width: 240, height: 240), true, 0)
来解释视网膜屏幕。查看 here 以了解有关如何使用此功能的更多详细信息。
我怀疑,虽然上面接受的答案对你有用,但它只是因为屏幕比例与图像比例相同才起作用。
由于您不是从屏幕本身渲染图像(您是从 UIImage
渲染到另一个 UIImage
),屏幕比例应该无关紧要。
您应该在创建上下文时传入图像的比例,如下所示:
UIGraphicsBeginImageContextWithOptions(CGSize(width: 240, height: 240), false, image.scale)
这是 Swift 3 中禁用任何插值的方法。
UIGraphicsBeginImageContextWithOptions(imageSize, false, UIScreen.main.scale)
let context = UIGraphicsGetCurrentContext()
context?.interpolationQuality = CGInterpolationQuality.none
此外,由于这通常用于绘制像素,您可能需要添加:
// Ensure the image is not drawn upside down
context?.saveGState()
context?.translateBy(x: 0.0, y: maxHeight)
context?.scaleBy(x: 1.0, y: -1.0)
// Make the drawing
context?.draw(yourImage, in: CGRect(x: 0, y: 0, width: maxWidth, height: maxHeight))
// Restore the GState of the context
context?.restoreGState()