2016-07-02 2 views
1

Je suis désolé de demander cela, mais je ne peux pas comprendre comment représenter un UIImage comme un tableau de UIColor pour chaque pixel. J'ai fait de mon mieux pour convertir UIImagePNG/JPEGRepresentation mais je n'ai pas pu obtenir le résultat désiré.UIImage à UIColor tableau de couleurs de pixel

+0

Que voulez-vous dire par "tableau UIColor"? Un tableau contenant la couleur de chaque pixel? –

+0

@CodeDifferent exactement – EBDOKUM

+0

@CodeDifferent Savez-vous, comment accomplir cela ou simplement vous demander? – EBDOKUM

Répondre

2

Ceci est simplement une traduction Swift de Olie's answer à la même question dans ObjC. Assurez-vous de lui donner un upvote aussi bien.

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

Notez que cela fonctionne plutôt lentement. Il faut 35 secondes au simulateur pour décoder une image de 15MP, et c'est sur un i7 quad-core.

+0

Merci beaucoup pour votre aide, j'apprécie vraiment cela! – EBDOKUM

+0

Cela entraînera beaucoup de frais généraux de réallocation de tableau. Les performances s'amélioreraient grandement si vous préallouez le tableau. En fait, cela n'a vraiment aucune raison d'utiliser 'NSMutableArray' à la place d'un 'tableau' Swift natif – Alexander

2

est ici une version 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 
    } 
}