将 [UInt8] 转换为白色透明图像
Convert [UInt8] into white and transparent image
我正在尝试从 [Uint8]
数组在 swift 中创建一个白色透明图像。该数组有 width * height
个元素,每个元素对应于透明度(alpha 值)。
到目前为止,我已经成功地创建了一张黑白图像:
guard let providerRef = CGDataProvider(data: Data.init(bytes: bitmapArray) as CFData) else { return nil }
guard let cgImage = CGImage(
width: width,
height: height,
bitsPerComponent: 8,
bitsPerPixel: 8,
bytesPerRow: width,
space: CGColorSpaceCreateDeviceGray(),
bitmapInfo: CGBitmapInfo.init(rawValue: CGImageAlphaInfo.none.rawValue),
provider: providerRef,
decode: nil,
shouldInterpolate: true,
intent: .defaultIntent
) else {
return nil
}
let image = UIImage(cgImage: cgImage)
不幸的是,正如我所说,这给了我一张黑白图像。
我想要的是将每个黑色像素(我的初始数组中的 0)变成一个完全透明的像素(我的数组只包含 0 或 255)。我怎么做 ?
PS:我尝试使用 CGImageAlphaInfo.alphaOnly
但我得到 "CGImageCreate: invalid image alphaInfo: 7"
如有任何帮助,我们将不胜感激。
我找到了一个解决方案,它在代码优雅方面并不完全令我满意,但可以完成工作。解决方案是创建黑白完全不透明图像,并使用 CIFilter 屏蔽所有黑色像素。
这是一个工作代码:
guard let providerRef = CGDataProvider(data: Data.init(bytes: bitmapArray) as CFData) else { return nil }
guard let cgImage = CGImage(
width: width,
height: height,
bitsPerComponent: 8,
bitsPerPixel: 8,
bytesPerRow: width,
space: CGColorSpaceCreateDeviceGray(),
bitmapInfo: CGBitmapInfo.init(rawValue: CGImageAlphaInfo.none.rawValue),
provider: providerRef,
decode: nil,
shouldInterpolate: true,
intent: .defaultIntent
) else {
return nil
}
let context = CIContext(options: nil)
let ciimage = CIImage(cgImage: cgImage)
guard let filter = CIFilter(name: "CIMaskToAlpha") else { return nil }
filter.setDefaults()
filter.setValue(ciimage, forKey: kCIInputImageKey)
guard let result = filter.outputImage else { return nil }
guard let newCgImage = context.createCGImage(result, from: result.extent) else { return nil }
return UIImage(cgImage: newCgImage)
欢迎提供您自己的(也许更多elegant/optimal)解决方案!
我找到了解决方法:由于 kCGAlphaImageOnly
受 CGBitmapContext
支持,您可以从数据创建位图上下文,然后从该上下文创建图像。这是Objective-C,但翻译成Swift应该不难:
CGContextRef ctx = CGBitmapContextCreate(
bitmapArray, width, height,
8, width, NULL, (CGBitmapInfo)kCGImageAlphaOnly
);
CGImageRef image = CGBitmapContextCreateImage(ctx);
我正在尝试从 [Uint8]
数组在 swift 中创建一个白色透明图像。该数组有 width * height
个元素,每个元素对应于透明度(alpha 值)。
到目前为止,我已经成功地创建了一张黑白图像:
guard let providerRef = CGDataProvider(data: Data.init(bytes: bitmapArray) as CFData) else { return nil }
guard let cgImage = CGImage(
width: width,
height: height,
bitsPerComponent: 8,
bitsPerPixel: 8,
bytesPerRow: width,
space: CGColorSpaceCreateDeviceGray(),
bitmapInfo: CGBitmapInfo.init(rawValue: CGImageAlphaInfo.none.rawValue),
provider: providerRef,
decode: nil,
shouldInterpolate: true,
intent: .defaultIntent
) else {
return nil
}
let image = UIImage(cgImage: cgImage)
不幸的是,正如我所说,这给了我一张黑白图像。
我想要的是将每个黑色像素(我的初始数组中的 0)变成一个完全透明的像素(我的数组只包含 0 或 255)。我怎么做 ?
PS:我尝试使用 CGImageAlphaInfo.alphaOnly
但我得到 "CGImageCreate: invalid image alphaInfo: 7"
如有任何帮助,我们将不胜感激。
我找到了一个解决方案,它在代码优雅方面并不完全令我满意,但可以完成工作。解决方案是创建黑白完全不透明图像,并使用 CIFilter 屏蔽所有黑色像素。
这是一个工作代码:
guard let providerRef = CGDataProvider(data: Data.init(bytes: bitmapArray) as CFData) else { return nil }
guard let cgImage = CGImage(
width: width,
height: height,
bitsPerComponent: 8,
bitsPerPixel: 8,
bytesPerRow: width,
space: CGColorSpaceCreateDeviceGray(),
bitmapInfo: CGBitmapInfo.init(rawValue: CGImageAlphaInfo.none.rawValue),
provider: providerRef,
decode: nil,
shouldInterpolate: true,
intent: .defaultIntent
) else {
return nil
}
let context = CIContext(options: nil)
let ciimage = CIImage(cgImage: cgImage)
guard let filter = CIFilter(name: "CIMaskToAlpha") else { return nil }
filter.setDefaults()
filter.setValue(ciimage, forKey: kCIInputImageKey)
guard let result = filter.outputImage else { return nil }
guard let newCgImage = context.createCGImage(result, from: result.extent) else { return nil }
return UIImage(cgImage: newCgImage)
欢迎提供您自己的(也许更多elegant/optimal)解决方案!
我找到了解决方法:由于 kCGAlphaImageOnly
受 CGBitmapContext
支持,您可以从数据创建位图上下文,然后从该上下文创建图像。这是Objective-C,但翻译成Swift应该不难:
CGContextRef ctx = CGBitmapContextCreate(
bitmapArray, width, height,
8, width, NULL, (CGBitmapInfo)kCGImageAlphaOnly
);
CGImageRef image = CGBitmapContextCreateImage(ctx);