【发布时间】:2020-10-24 19:07:57
【问题描述】:
我在使用另一个 UIImage 作为掩码来掩蔽 UIImage 时遇到了一些问题。我尝试过使用masking(_:) Core Graphics 函数(Objective C 中的CGImageCreateWithMask),但蒙版图像的输出显示没有任何蒙版。它只是显示正常的图像。
我使用了两种方法来做到这一点:首先,通过传递蒙版图像本身来应用。其次,通过使用 CGImage 初始化程序从该图像创建一个掩码并改为传递它。这是执行此操作的函数:
func performMask(_ originalImage:UIImage, maskImage:UIImage) -> UIImage? {
guard let originalImageCGImage = originalImage.cgImage, let maskImageCGImage = maskImage.cgImage else { return nil }
print("Method 1 - Image (UIImage):")
print("\(String(describing: maskImage.cgImage))\n\n")
print("Method 2 - Mask (CGImage):")
let maskImage2 = CGImage(
maskWidth: Int(maskImage.size.width * maskImage.scale),
height: Int(maskImage.size.height * maskImage.scale),
bitsPerComponent: maskImageCGImage.bitsPerComponent,
bitsPerPixel: maskImageCGImage.bitsPerPixel,
bytesPerRow: maskImageCGImage.bytesPerRow,
provider: maskImageCGImage.dataProvider!,
decode: nil,
shouldInterpolate: true
)
print("\(String(describing: maskImage2))\n\n")
let maskedImage = originalImageCGImage.masking(maskImage.cgImage!) // Output: Method 1
// let maskedImage2 = originalImageCGImage.masking(maskImage2!) // Output: Method 2
return UIImage(cgImage: maskedImage!)
}
这是我得到的控制台输出,显示了上面的打印语句:
Method 1 - Image (UIImage):
Optional(<CGImage 0x104223890> (DP)
<<CGColorSpace 0x281414960> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile)>
width = 320, height = 320, bpc = 8, bpp = 8, row bytes = 640
kCGImageAlphaNone | 0 (default byte order) | kCGImagePixelFormatPacked
is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes)
Method 2 - Mask (CGImage):
Optional(<CGImage 0x104223e90> (DP)
<(null)>
width = 320, height = 320, bpc = 8, bpp = 8, row bytes = 640
kCGImageAlphaNone | 0 (default byte order) | kCGImagePixelFormatPacked
is mask? Yes, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes)
我的一个理论是图像在kCGColorSpaceModelMonochrome 颜色空间中是问题所在。 masking(_:) 函数的文档说:
"如果蒙版是图像,则必须在DeviceGray色彩空间中, 不得有 alpha 分量,并且本身不能被 图像掩码或掩码颜色。”
但是,标题给出了不太严格的色彩空间要求:
"如果 `mask' 是图像,那么它必须在单色空间中 (例如 DeviceGray、GenericGray 等),可能没有 alpha,并且可能 本身不会被图像遮罩或遮罩颜色遮盖。”
无论我做什么,我都只会为我的蒙版图像(不是 DeviceGray)获得一个 kCGColorSpaceModelMonochrome 色彩空间 - 应该基于后一个语句,但不是第一个语句.
掩码图像本身是使用UIGraphicsImageRenderer 的image(actions: (UIGraphicsImageRendererContext) -> Void) 函数从UIBezierPath 生成的,在调试器中对我来说看起来没问题(它是一个不规则形状的黑白图像)——它只是不能用作面具。
注意:我正在尝试从 UIGraphicsImageRenderer 中的 iOS 12 内存使用优化中受益,详情请参阅 2018 年的 WWDC 演讲“图像和图形最佳实践” (29:15),但遗憾的是没有手动指定生成图像的颜色空间的方法。这是一个功能,但我希望有一种方法可以覆盖它。
https://developer.apple.com/videos/play/wwdc2018/219/
有谁知道如何让这个掩码操作正常工作?
【问题讨论】:
-
为什么需要这个蒙面的 UIImage?如果这是一些自定义 UIView,您可以尝试设置 CALayer 的掩码。
标签: ios swift core-graphics mask masking