【问题标题】:UIImage to UIColor array of pixel colorsUIImage 到 UIColor 像素颜色数组
【发布时间】:2016-07-02 19:01:43
【问题描述】:

很抱歉问这个问题,但我不知道如何将 UIImage 表示为每个像素的 UIColor 数组。我已尽力转换 UIImagePNG/JPEGRepresentation,但无法获得所需的结果。

【问题讨论】:

  • “UIColor 数组”是什么意思?包含每个像素颜色的数组?
  • @CodeDifferent 完全一致
  • @CodeDifferent 你知道吗,如何做到这一点或只是想知道?
  • 当我要求澄清时,不能保证一定会回答您的问题。这评论似乎有点不尊重
  • 没关系。不要急于或催促任何人回答。这是一个志愿者网站,你不知道还有什么占用他们的时间。另外,我更改了byteIndex 的计算方式。确保更新您的代码。

标签: swift uiimage uicolor


【解决方案1】:

这是一个 Swiftier 版本(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
    }
}

【讨论】:

  • 应用程序在此行崩溃:let red = CGFloat(rawData[byteIndex]) / 255.0 为什么?!
【解决方案2】:

这只是 Swift 对 Olie's answer 对 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]
    }
}

请注意,这运行相当缓慢。模拟器解码 15MP 图像需要 35 秒,而且是在四核 i7 上。

【讨论】:

  • 非常感谢您的帮助,我真的很感激!
  • 这将导致数组重新分配的大量开销。如果您预先分配数组,性能会大大提高。事实上,这真的没有理由使用NSMutableArray 而不是原生的Swift Array
【解决方案3】:

获取像素试试

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)

}

【讨论】:

  • 来自 UIImage 的像素值
猜你喜欢
  • 2013-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
相关资源
最近更新 更多