Конвертировать [UInt8] в белое и прозрачное изображение - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь быстро создать белое и прозрачное изображение из массива [Uint8]. Массив имеет width * height элементов, и каждый элемент соответствует прозрачности (альфа-значение).

Пока мне удалось создать черно-белое изображение, используя это:

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: недопустимое изображение alphaInfo: 7»

Любая помощь будет оценена.

1 Ответ

0 голосов
/ 07 января 2019

Я нашел решение, которое не совсем удовлетворяет меня с точки зрения элегантности кода, но выполняет свою работу. Решение состоит в том, чтобы создать это черно-белое полностью непрозрачное изображение и замаскировать все черные пиксели с помощью фильтра 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)

Не стесняйтесь предложить свое собственное (возможно, более элегантное / оптимальное) решение!

...