Swift에서 CoreGraphics의 자제 색도 키를 사용하여 필터를 합성하는 제작

5641 단어 SwiftCoreGraphicsiOS

개시하다


캐릭터 배경을 잘라서 합성을 하려는 상황 등.
공상 과학 영화에서 색도 키 합성을 사용하여 표현하다.
iOS의 CIFilter와 비슷한 게 있는지 찾고 있어요.
찾을 수 없어서 간단하게 할 수 있는 범위 내에서 시도해 봤어요.
색도 키가 합성된 howto에는 각양각색의 견해가 있기 때문에 너무 어려운 일을 하지 마라
이미지 데이터를 픽셀 스캐닝의 샘플로 고려해 주십시오.

메서드



터치 위치의 <색상 A> 가져오기

<색상 A> = 흰색/그 외 = 검은색 <이치화된 이미지 B>의 생성

원래 이미지 및 <2치 이미지 B> 작성, 검정색만 자르기

배경 이미지 및 작성

1: 터치 위치 색상(UIColor)을 가져오는 코드를 먼저 그립니다.


extension은 UIImage로 제작됩니다.
<포인트>
RGBA는 1byte씩, 1pixel은 4byte이니까.
(var pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4)
extension UIImage {
    func getPixelColor(pos: CGPoint) -> UIColor {        
        var pixelData = CGDataProviderCopyData(CGImageGetDataProvider(self.CGImage))
        var data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
        var pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4
        var r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
        var g = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
        var b = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
        var a = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)
        return UIColor(red: r, green: g, blue: b, alpha: a)
    }
}

2. UIImage의 가로 세로 1pix씩 전체 스캔하여 객체의 색상(1 Color)이 흰색이면 검은색


쓰기는 UIImage의 extension을 반환합니다.
<포인트>
for로 그림의 폭과 높이를 회전하여point=(x, y)의 색을 가져옵니다
RGBA가 각각 1byte이므로 1pixel은 4byte(let newByteLength = width*height*4)
CGImageCreate(RGB 바이트에서 정렬하여 UIImage 만들기)를 사용하여 UIImage로 돌아가기
//入力した色と同じ色を白に塗りつぶす
func getMaskImageFromTappedColor(_tColor:UIColor) -> UIImage? {
    var _image = self
    var _width = Int(_image.size.width)
    var _height = Int(_image.size.height)
    var _imageData = _image.imageData()
    var imageBytes : UnsafeMutablePointer<Byte>;
    let newByteLength = _width * _height * 4
    imageBytes = UnsafeMutablePointer<Byte>.alloc(newByteLength)
    var _cnt = 0;
    for x in 0..<_width {
        for y in 0..<_height {
            var point = (x, y)
            var color = UIImage.colorAtPoint(
                point,
                imageWidth: _width,
                withData: _imageData
            )
            var i: Int = ((Int(_width) * Int(y)) + Int(x)) * 4
            if(color == _tColor){
                imageBytes[i] = Byte(255) // red
                imageBytes[i+1] = Byte(255); // green
                imageBytes[i+2] = Byte(255); // blue
                imageBytes[i+3] = Byte(255); // alpha
            }else{
                imageBytes[i] = Byte(0) // red
                imageBytes[i+1] = Byte(0); // green
                imageBytes[i+2] = Byte(0); // blue
                imageBytes[i+3] = Byte(255); // alpha
            }
        }
    } 
    var provider = CGDataProviderCreateWithData(nil,imageBytes, UInt(newByteLength), nil)
    var bitsPerComponent:UInt = 8
    var bitsPerPixel:UInt = bitsPerComponent * 4
    var bytesPerRow:UInt = UInt(4) * UInt(_width)
    var colorSpaceRef = CGColorSpaceCreateDeviceRGB()
    var bitmapInfo = CGBitmapInfo.ByteOrderDefault
    var renderingIntent = kCGRenderingIntentDefault
    var cgImage = CGImageCreate(UInt(_width), UInt(_height), bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, nil, false, renderingIntent)
    return UIImage(CGImage: cgImage)
}

3. 이치화된 이미지에서 extension에서 원시 이미지를 전송하는 함수를 만듭니다

func getMaskedImage(maskImage:UIImage!) -> UIImage {        
    let maskImageReference:CoreImage.CGImage? = maskImage?.CGImage
    let mask = CGImageMaskCreate(CGImageGetWidth(maskImageReference),
        CGImageGetHeight(maskImageReference),
        CGImageGetBitsPerComponent(maskImageReference),
        CGImageGetBitsPerPixel(maskImageReference),
        CGImageGetBytesPerRow(maskImageReference),
        CGImageGetDataProvider(maskImageReference),nil,false)
    let maskedImageReference = CGImageCreateWithMask(self.CGImage, mask)
    let maskedImage = UIImage(CGImage: maskedImageReference)
    return maskedImage!
}

4. 마지막으로 UIView에 터치 베건 방법을 넣고 터치 좌표를 extension에 전달하는 처리를 적는다

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {        
    let t = touches.anyObject() as UITouch
    //指定したのImageViewの中での座標を取得する
    let point = t.locationInView(self.shipImageView)
    //get color you touched
    var color : UIColor! = self.shipImageView?.image!.getPixelColor(point)
    var filteredImage = self.shipImageView?.image!.getFilteredImage(color)
    self.shipImageView?.image = filteredImage
}

완성


터치 위치 색을 배경으로 투명한 샘플을 만들었습니다.

끝맺다


이번에는 터치한 부분을 제거해서 배경을 잘라볼게요.
나는 이치화된 이미지의 제작 방법에 따라 다양한 커팅 방법이 가능하다고 생각한다.
예를 들어 이미지의 밝기 관점에서 한도값을 만들고 이치화 이미지를 만든다
iOS의 얼굴 인식을 통해 얼굴의 일부만 동그랗게 자르는 이치화된 이미지 등을 제작한다
다양한 즐거움을 누리세요!
(github)
https://github.com/oggata/PhotoChromakeyDemo

좋은 웹페이지 즐겨찾기