在Swift中将像素数组转换为UIImage

我一直在尝试找出如何在Swift中将rgb像素数据数组转换为UIImage。

我将每个像素的rgb数据保持在一个简单的结构中:

public struct PixelData {

var a: Int

var r: Int

var g: Int

var b: Int

}

我已经实现了以下功能,但是生成的图像不正确:

func imageFromARGB32Bitmap(pixels:[PixelData], width: Int, height: Int)-> UIImage {

let rgbColorSpace = CGColorSpaceCreateDeviceRGB()

let bitmapInfo:CGBitmapInfo = CGBitmapInfo(CGImageAlphaInfo.PremultipliedFirst.rawValue)

let bitsPerComponent:Int = 8

let bitsPerPixel:Int = 32

assert(pixels.count == Int(width * height))

var data = pixels // Copy to mutable []

let providerRef = CGDataProviderCreateWithCFData(

NSData(bytes: &data, length: data.count * sizeof(PixelData))

)

let cgim = CGImageCreate(

width,

height,

bitsPerComponent,

bitsPerPixel,

width * Int(sizeof(PixelData)),

rgbColorSpace,

bitmapInfo,

providerRef,

nil,

true,

kCGRenderingIntentDefault

)

return UIImage(CGImage: cgim)!

}

关于如何正确地将rgb数组转换为UIImage的任何提示或指针?

回答:

这是iOS创建的解决方案UIImage。有关macOS和的解决方案NSImage,请参见此答案。

唯一的问题是结构中的数据类型PixelData需要为UInt8。我在Playground中使用以下内容创建了测试图像:

public struct PixelData {

var a: UInt8

var r: UInt8

var g: UInt8

var b: UInt8

}

var pixels = [PixelData]()

let red = PixelData(a: 255, r: 255, g: 0, b: 0)

let green = PixelData(a: 255, r: 0, g: 255, b: 0)

let blue = PixelData(a: 255, r: 0, g: 0, b: 255)

for _ in 1...300 {

pixels.append(red)

}

for _ in 1...300 {

pixels.append(green)

}

for _ in 1...300 {

pixels.append(blue)

}

let image = imageFromARGB32Bitmap(pixels: pixels, width: 30, height: 30)


我更新imageFromARGB32Bitmap为使用Swift4。该函数现在返回a,UIImage?并在出现任何问题时guard用于返回nil

func imageFromARGB32Bitmap(pixels: [PixelData], width: Int, height: Int) -> UIImage? {

guard width > 0 && height > 0 else { return nil }

guard pixels.count == width * height else { return nil }

let rgbColorSpace = CGColorSpaceCreateDeviceRGB()

let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)

let bitsPerComponent = 8

let bitsPerPixel = 32

var data = pixels // Copy to mutable []

guard let providerRef = CGDataProvider(data: NSData(bytes: &data,

length: data.count * MemoryLayout<PixelData>.size)

)

else { return nil }

guard let cgim = CGImage(

width: width,

height: height,

bitsPerComponent: bitsPerComponent,

bitsPerPixel: bitsPerPixel,

bytesPerRow: width * MemoryLayout<PixelData>.size,

space: rgbColorSpace,

bitmapInfo: bitmapInfo,

provider: providerRef,

decode: nil,

shouldInterpolate: true,

intent: .defaultIntent

)

else { return nil }

return UIImage(cgImage: cgim)

}


此函数可以用作的convenience初始化程序UIImage。这是实现:

extension UIImage {

convenience init?(pixels: [PixelData], width: Int, height: Int) {

guard width > 0 && height > 0, pixels.count == width * height else { return nil }

var data = pixels

guard let providerRef = CGDataProvider(data: Data(bytes: &data, count: data.count * MemoryLayout<PixelData>.size) as CFData)

else { return nil }

guard let cgim = CGImage(

width: width,

height: height,

bitsPerComponent: 8,

bitsPerPixel: 32,

bytesPerRow: width * MemoryLayout<PixelData>.size,

space: CGColorSpaceCreateDeviceRGB(),

bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue),

provider: providerRef,

decode: nil,

shouldInterpolate: true,

intent: .defaultIntent)

else { return nil }

self.init(cgImage: cgim)

}

}

这是一个用法示例:

// Generate a 500x500 image of randomly colored pixels

let height = 500

let width = 500

var pixels: [PixelData] = .init(repeating: .init(a: 0, r: 0, g: 0, b: 0), count: width * height)

for index in pixels.indices {

pixels[index].a = 255

pixels[index].r = .random(in: 0...255)

pixels[index].g = .random(in: 0...255)

pixels[index].b = .random(in: 0...255)

}

let image = UIImage(pixels: pixels, width: width, height: height)

以上是 在Swift中将像素数组转换为UIImage 的全部内容, 来源链接: utcz.com/qa/427538.html

回到顶部