Swift 파헤치기

[Swift4] 이미지 픽셀로 변환해서 처리하기

doflamingo 2018. 11. 7. 11:15

Swift4) Pixel 단위 변환 코드




픽셀 Structure

32비트짜리에서 LSB부터 8비트씩 RGBA값을 갖기 때문에 아래와 같은 시프트 연산을 통해서 Structure을 구성했다.

public struct RGBAPixel {
   public var raw: UInt32
   public var red: UInt8 {
       get { return UInt8(raw & 0xFF) }
       set { raw = UInt32(newValue) | (raw & 0xFFFFFF00)}
   }
   public var green: UInt8 {
       get { return UInt8((raw & 0xFF00) >> 8) }
       set { raw = (UInt32(newValue) << 8) | (raw & 0xFFFF00FF)}
   }
   public var blue: UInt8 {
       get { return UInt8((raw & 0xFF0000) >> 16) }
       set { raw = (UInt32(newValue) << 16) | (raw & 0xFF00FFFF)}
   }
   public var alpha: UInt8 {
       get { return UInt8((raw & 0xFF000000) >> 24) }
       set { raw = (UInt32(newValue) << 24) | (raw & 0x00FFFFFF)}
   }
}


이미지 변환 코드

func changeWhiteToTransparent(image: UIImage) -> UIImage {

   let height = Int(image.size.height)
   let width = Int(image.size.width)

   let bitsPerComponents = 8
   let bytesPerRow = 4 * width
   let colorspace = CGColorSpaceCreateDeviceRGB()
   let rawdata = UnsafeMutablePointer<RGBAPixel>.allocate(capacity: width*height)
   let bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Big.rawValue | CGImageAlphaInfo.premultipliedLast.rawValue
   let imageContext = CGContext(data: rawdata, width: width, height: height, bitsPerComponent: bitsPerComponents, bytesPerRow: bytesPerRow, space: colorspace, bitmapInfo: bitmapInfo)

   imageContext?.draw(image.cgImage!, in: CGRect(origin: CGPoint.zero, size: image.size))

   let pixels = UnsafeMutableBufferPointer<RGBAPixel>(start: rawdata, count: width*height)

   for y in 0 ..< height {
       for x in 0 ..< width {
           var p = pixels[x+y*width]
           p.alpha = 0
           pixels[x+y*width] = p
       }
   }

   let outcontext = CGContext(data: pixels.baseAddress, width: width, height: height, bitsPerComponent: bitsPerComponents, bytesPerRow: bytesPerRow, space: colorspace, bitmapInfo: bitmapInfo, releaseCallback: nil, releaseInfo: nil)
   // let cgimg = outcontext?.makeImage()
   let outImage = UIImage(cgImage: (outcontext?.makeImage())!)

   return outImage

}

for y in 0 ..< height {
   for x in 0 ..< width {
       var p = pixels[x+y*width]
       p.alpha = 0
       pixels[x+y*width] = p
   }
}

위의 부분을 변경해서 픽셀 단위로 변환시키면 된다.


출처: https://www.youtube.com/watch?v=S9fbO9l4mVM