2016-07-02 4 views
1

Прошу простить об этом, но я не могу понять, как представить UIImage как массив UIColor для каждого пикселя. Я попытался изо всех сил с преобразованием UIImagePNG/JPEGRepresentation, но не смог получить желаемый результат.UIImage to UIColor массив пиксельных цветов

+0

Что вы имеете в виду под "UIColor массив"? Массив, содержащий цвет каждого пикселя? –

+0

@CodeDifferent точно – EBDOKUM

+0

@CodeDifferent Знаете ли вы, как это сделать или просто интересно? – EBDOKUM

ответ

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] 
    } 
} 

Обратите внимание, что это работает довольно медленно. Требуется 35 секунд для того, чтобы симулятор мог декодировать 15-мегапиксельное изображение, и это на четырехъядерном процессоре i7.

+0

Большое спасибо за вашу помощь, я действительно ценю это! – EBDOKUM

+0

Это приведет к большому количеству накладных расходов при перераспределении массива. Производительность значительно улучшится, если вы предварительно выделите массив. На самом деле у этого действительно нет причин использовать 'NSMutableArray' вместо собственного Swift' Array' – Alexander

2

Вот версия 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 
    } 
} 
Смежные вопросы