如何在绘制和合成 UIImage 时应用比例
How to apply scale when drawing and composing UIImage
我有以下func
问题。
extension UIImage
{
var width: CGFloat
{
return size.width
}
var height: CGFloat
{
return size.height
}
private static func circularImage(diameter: CGFloat, color: UIColor) -> UIImage
{
UIGraphicsBeginImageContextWithOptions(CGSize(width: diameter, height: diameter), false, 0)
let context = UIGraphicsGetCurrentContext()!
context.saveGState()
let rect = CGRect(x: 0, y: 0, width: diameter, height: diameter)
context.setFillColor(color.cgColor)
context.fillEllipse(in: rect)
context.restoreGState()
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
private func addCentered(image: UIImage, tintColor: UIColor) -> UIImage
{
let topImage = image.withTintColor(tintColor, renderingMode: .alwaysTemplate)
let bottomImage = self
UIGraphicsBeginImageContext(size)
let bottomRect = CGRect(x: 0, y: 0, width: bottomImage.width, height: bottomImage.height)
bottomImage.draw(in: bottomRect)
let topRect = CGRect(x: (bottomImage.width - topImage.width) / 2.0,
y: (bottomImage.height - topImage.height) / 2.0,
width: topImage.width,
height: topImage.height)
topImage.draw(in: topRect, blendMode: .normal, alpha: 1.0)
let mergedImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return mergedImage
}
}
它们工作正常,但我如何正确应用 UIScreen.main.scale
以支持视网膜屏幕?
我查看了已完成的工作here,但还想不出来。
有什么想法吗?
访问 UIScreen.main.scale
本身有点问题,因为您只能从主线程访问它(而您通常希望在后台线程上进行较重的图像处理)。所以我建议改用其中一种方法。
首先,您可以将UIGraphicsBeginImageContext(size)
替换为
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
最后一个参数(0.0
)是一个scale
,并且根据docs》如果指定值为0.0,比例因子设置为比例因子设备的主屏幕。"
相反,如果您想保留原始图像在结果 UIImage
上的比例,您可以这样做:在 topImage.draw
之后,不是使用 UIGraphicsGetImageFromCurrentImageContext
获取 UIImage,而是使用
let cgImage = context.makeImage()
然后使用原始图像的比例和方向构造 UIImage(与默认值相反)
let mergedImage = UIImage(
cgImage: cgImage,
scale: image.scale,
orientation: image.opientation)
我有以下func
问题。
extension UIImage
{
var width: CGFloat
{
return size.width
}
var height: CGFloat
{
return size.height
}
private static func circularImage(diameter: CGFloat, color: UIColor) -> UIImage
{
UIGraphicsBeginImageContextWithOptions(CGSize(width: diameter, height: diameter), false, 0)
let context = UIGraphicsGetCurrentContext()!
context.saveGState()
let rect = CGRect(x: 0, y: 0, width: diameter, height: diameter)
context.setFillColor(color.cgColor)
context.fillEllipse(in: rect)
context.restoreGState()
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
private func addCentered(image: UIImage, tintColor: UIColor) -> UIImage
{
let topImage = image.withTintColor(tintColor, renderingMode: .alwaysTemplate)
let bottomImage = self
UIGraphicsBeginImageContext(size)
let bottomRect = CGRect(x: 0, y: 0, width: bottomImage.width, height: bottomImage.height)
bottomImage.draw(in: bottomRect)
let topRect = CGRect(x: (bottomImage.width - topImage.width) / 2.0,
y: (bottomImage.height - topImage.height) / 2.0,
width: topImage.width,
height: topImage.height)
topImage.draw(in: topRect, blendMode: .normal, alpha: 1.0)
let mergedImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return mergedImage
}
}
它们工作正常,但我如何正确应用 UIScreen.main.scale
以支持视网膜屏幕?
我查看了已完成的工作here,但还想不出来。
有什么想法吗?
访问 UIScreen.main.scale
本身有点问题,因为您只能从主线程访问它(而您通常希望在后台线程上进行较重的图像处理)。所以我建议改用其中一种方法。
首先,您可以将UIGraphicsBeginImageContext(size)
替换为
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
最后一个参数(0.0
)是一个scale
,并且根据docs》如果指定值为0.0,比例因子设置为比例因子设备的主屏幕。"
相反,如果您想保留原始图像在结果 UIImage
上的比例,您可以这样做:在 topImage.draw
之后,不是使用 UIGraphicsGetImageFromCurrentImageContext
获取 UIImage,而是使用
let cgImage = context.makeImage()
然后使用原始图像的比例和方向构造 UIImage(与默认值相反)
let mergedImage = UIImage(
cgImage: cgImage,
scale: image.scale,
orientation: image.opientation)