2017-05-09 1 views
2

実際にはアルファチャンネルで黒くなっている巨大な32ビットPNGを取り込み、iOSアプリでメモリにやさしい方法で提示しようとしています。kCGImageAlphaOnlyレンダリングされたCGImageの色を変更します

は「アルファのみ」CGContextに私は画像を再レンダリングしようとしたことを実行します。

extension UIImage { 
    func toLayer() -> CALayer? { 
     let cgImage = self.cgImage! 
     let height = Int(self.size.height) 
     let width = Int(self.size.width) 

     let colorSpace = CGColorSpaceCreateDeviceGray() 
     let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: width, space: colorSpace, bitmapInfo: CGImageAlphaInfo.alphaOnly.rawValue)! 

     context.draw(cgImage, in: CGRect(origin: .zero, size: self.size)) 
     let image = context.makeImage()! 

     let layer = CALayer() 
     layer.contents = image 
     layer.contentsScale = self.scale 

     return layer 
    } 
} 

これは素晴らしいです!メモリ使用量は180MBから約18MBに減少しました。これは実際に予想したよりも優れています。

画像の黒色(または、今は不透明な)部分はもはや黒色ではなく、白色であるという問題があります。

不透明なビットの色を変更するのは簡単な修正が必要なようですが、私はオンラインでその情報を見つけることができません。アイデアはありますか?

答えて

0

私は自分の質問に答えることができました。アルファ専用画像を出力レイヤーのmaskcontentsとして設定することで、レイヤーの背景色を任意の値(グレースケール以外の値も含む)に設定して、メモリのメリットを引き続き維持できます。

私は確かにこの方法に興味だけではないですので、私は最終的なコードが含まれていました:

extension UIImage { 
    func to8BitLayer(color: UIColor = .black) -> CALayer? { 
     guard let cgImage = self.cgImage else { return nil } 
     let height = Int(self.size.height * scale) 
     let width = Int(self.size.width * scale) 

     let colorSpace = CGColorSpaceCreateDeviceGray() 
     guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: width, space: colorSpace, bitmapInfo: CGImageAlphaInfo.alphaOnly.rawValue) else { 
      print("Couldn't create CGContext") 
      return nil 
     } 

     context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height)) 
     guard let image = context.makeImage() else { 
      print("Couldn't create image from context") 
      return nil 
     } 

     // Note that self.size corresponds to the non-scaled (retina) dimensions, so is not the same size as the context 
     let frame = CGRect(origin: .zero, size: self.size) 

     let mask = CALayer() 
     mask.contents = image 
     mask.contentsScale = scale 
     mask.frame = frame 

     let layer = CALayer() 
     layer.backgroundColor = color.cgColor 
     layer.mask = mask 
     layer.contentsScale = scale 
     layer.frame = frame 

     return layer 
    } 
} 
関連する問題