我已经被这个问题困扰了几天,但找不到解决方法。我有一个带透明背景的UIImageView,它位于另一个视图之上(在此示例中仅为具有蓝色背景颜色的UIView)。出于某种原因,即使它的 alpha 值为0(在这种情况下完全红色没有 alpha 值的图像会呈现粉色),它也会混合一种颜色。期望的输出是,它将像没有 alpha 值的黑色一样清晰地显示。
如果在白色上方,则表现如预期(它是透明的,并显示白色)。我尝试过使用不同的CGContext创建方式和不同的CALayer混合模式,但无法使它不混合没有alpha值的颜色。
以下是可复制该问题的示例代码:
import UIKit
import PlaygroundSupport
import CoreGraphics
class MyViewController : UIViewController {
var pixelPointer: UnsafeMutablePointer<UInt8>!
let imageWidth = 20
let imageHeight = 20
override func loadView() {
let view = UIView()
view.backgroundColor = .blue
let viewSize: CGFloat = 150
// Test Image
pixelPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: imageWidth * imageWidth * 4)
let ctx = CGContext(data: pixelPointer,
width: imageWidth,
height: imageHeight,
bitsPerComponent: 8,
bytesPerRow: 4 * imageWidth,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!
for x in 0 ..< imageWidth {
for y in 0 ..< imageHeight {
if y == 7 || y == 8 || y == 9 {
// Red No Alpha -> Expected to be transparent
setColorFor(255, g: 0, b: 0, a: 0, x: x, y: y)
} else if y == 10 || y == 11 || y == 12 {
// Black No Alpha -> Is transparent
setColorFor(0, g: 0, b: 0, a: 0, x: x, y: y)
} else {
// Red
setColorFor(255, g: 0, b: 0, a: 255, x: x, y: y)
}
}
}
let cgImage = ctx.makeImage()!
// ImageView with Clear Background
let imageViewClearBackground = UIImageView()
imageViewClearBackground.backgroundColor = .clear
imageViewClearBackground.frame.origin = CGPoint(x: 10, y: 10)
imageViewClearBackground.layer.borderColor = UIColor.black.cgColor
imageViewClearBackground.layer.borderWidth = 1
imageViewClearBackground.frame.size = CGSize(width: viewSize, height: viewSize)
imageViewClearBackground.layer.magnificationFilter = CALayerContentsFilter.nearest
imageViewClearBackground.image = UIImage(cgImage: cgImage)
view.addSubview(imageViewClearBackground)
// ImageView with White Background
let imageViewWhiteBackground = UIImageView()
imageViewWhiteBackground.layer.borderColor = UIColor.black.cgColor
imageViewWhiteBackground.layer.borderWidth = 1
imageViewWhiteBackground.backgroundColor = .white
imageViewWhiteBackground.frame.size = CGSize(width: viewSize, height: viewSize)
imageViewWhiteBackground.frame.origin = CGPoint(x: viewSize + 20, y: 10)
imageViewWhiteBackground.layer.magnificationFilter = CALayerContentsFilter.nearest
imageViewWhiteBackground.image = UIImage(cgImage: cgImage)
view.addSubview(imageViewWhiteBackground)
self.view = view
}
func setColorFor(_ r: Int, g: Int, b: Int, a: Int, x: Int, y: Int) {
let offset = (y * Int(imageWidth) * 4) + x * 4
pixelPointer[offset+0] = UInt8(r)
pixelPointer[offset+1] = UInt8(g)
pixelPointer[offset+2] = UInt8(b)
pixelPointer[offset+3] = UInt8(a)
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()