UIImage到UIColor的像素颜色数组



我很抱歉问这个,但我不能弄清楚如何表示一个UIImage为每个像素的UIColor数组。我已经尽力转换UIImagePNG/JPEGRepresentation,但无法得到所需的结果。

这是一个Swift 3版本:

extension UIImage {
    var colors: [UIColor]? {
        var colors = [UIColor]()
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        guard let cgImage = cgImage else {
            return nil
        }
        let width = Int(size.width)
        let height = Int(size.height)
        var rawData = [UInt8](repeating: 0, count: width * height * 4)
        let bytesPerPixel = 4
        let bytesPerRow = bytesPerPixel * width
        let bytesPerComponent = 8
        let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue
        let context = CGContext(data: &rawData,
                                width: width,
                                height: height,
                                bitsPerComponent: bytesPerComponent,
                                bytesPerRow: bytesPerRow,
                                space: colorSpace,
                                bitmapInfo: bitmapInfo)
        let drawingRect = CGRect(origin: .zero, size: CGSize(width: width, height: height))
        context?.draw(cgImage, in: drawingRect)
        for x in 0..<width {
            for y in 0..<height {
                let byteIndex = (bytesPerRow * x) + y * bytesPerPixel
                let red = CGFloat(rawData[byteIndex]) / 255.0
                let green = CGFloat(rawData[byteIndex + 1]) / 255.0
                let blue = CGFloat(rawData[byteIndex + 2]) / 255.0
                let alpha = CGFloat(rawData[byteIndex + 3]) / 255.0
                let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
                colors.append(color)
            }
        }
        return colors
    }
}

这只是Swift对Olie在ObjC中对相同问题的回答的翻译。一定要给他点赞。

extension UIImage {
    func colorArray() -> [UIColor] {
        let result = NSMutableArray()
        let img = self.CGImage
        let width = CGImageGetWidth(img)
        let height = CGImageGetHeight(img)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        var rawData = [UInt8](count: width * height * 4, repeatedValue: 0)
        let bytesPerPixel = 4
        let bytesPerRow = bytesPerPixel * width
        let bytesPerComponent = 8
        let bitmapInfo = CGImageAlphaInfo.PremultipliedLast.rawValue | CGBitmapInfo.ByteOrder32Big.rawValue
        let context = CGBitmapContextCreate(&rawData, width, height, bytesPerComponent, bytesPerRow, colorSpace, bitmapInfo)
        CGContextDrawImage(context, CGRectMake(0, 0, CGFloat(width), CGFloat(height)), img);
        for x in 0..<width {
            for y in 0..<height {
                let byteIndex = (bytesPerRow * x) + y * bytesPerPixel
                let red   = CGFloat(rawData[byteIndex]    ) / 255.0
                let green = CGFloat(rawData[byteIndex + 1]) / 255.0
                let blue  = CGFloat(rawData[byteIndex + 2]) / 255.0
                let alpha = CGFloat(rawData[byteIndex + 3]) / 255.0
                let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
                result.addObject(color)
            }
        }
        return (result as NSArray) as! [UIColor]
    }
}

注意,这运行得相当慢。模拟器解码一张1500万像素的图像需要35秒,这还是在四核i7上。

获取像素试试

let image = UIImage(named: "pic2.png")
if let cgImage = image?.cgImage, let data = cgImage.dataProvider?.data, let bytes = CFDataGetBytePtr(data){
assert(cgImage.colorSpace?.model == .rgb)
var stringArray = [String]()
let bytesPerPixel = cgImage.bitsPerPixel / cgImage.bitsPerComponent
for y in 0 ..< cgImage.height{
    for x in 0 ..< cgImage.width{
        let offset = (y * cgImage.bytesPerRow) + ( x * bytesPerPixel)
        let components = (r: bytes[offset], g: bytes[offset + 1], b: bytes[offset + 2])
        stringArray.append("[x: (x), y:(y)] (components)")
    }
}
print(stringArray)

}

最新更新