Pono
Pono

Reputation: 11776

Swift3 - Crop-out or trim boring pixels from the image with CoreGraphics or CoreImage

I'm wondering if there's an easy way to trim/crop-out an image with CoreGraphics or CoreImage and Swift3?

Given an input image on the top (with red/rose background) we trim those red pixels away so that only the real, interesting bits are left?

Trim an image with Swift3

Upvotes: 0

Views: 176

Answers (1)

Josh Homann
Josh Homann

Reputation: 16327

I just answered a subset of a similar question over here: Iterate over individual pixels of a UIImage with height information

Here's how you get the top and bottom unique pixels.

    func pixelNotMatchingTopLeftColor(in image: UIImage, first isFirst: Bool) -> CGPoint? {
        let width = Int(image.size.width)
        let height = Int(image.size.height)
        guard width > 1 || height < 1 else {
            return nil
        }
        if let cfData:CFData = image.cgImage?.dataProvider?.data, let pointer = CFDataGetBytePtr(cfData) {
            let cornerPixelRed = pointer.pointee
            let cornerPixelGreen = pointer.advanced(by: 0).pointee
            let cornerPixelBlue = pointer.advanced(by: 1).pointee
            let cornerPixelAlpha = pointer.advanced(by: 2).pointee
            let bytesPerpixel = 4
            let firstPixel = 1 * bytesPerpixel
            let lastPixel = width * height * bytesPerpixel - 1 * bytesPerpixel
            let range = isFirst ? stride(from: firstPixel, through: lastPixel, by: bytesPerpixel) :
                                  stride(from: lastPixel, through: firstPixel + bytesPerPixel, by: -bytesPerpixel)
            for pixelAddress in range {
                    if pointer.advanced(by: pixelAddress).pointee != cornerPixelRed ||     //Red
                       pointer.advanced(by: pixelAddress + 1).pointee != cornerPixelGreen || //Green
                       pointer.advanced(by: pixelAddress + 2).pointee != cornerPixelBlue || //Blue
                       pointer.advanced(by: pixelAddress + 3).pointee != cornerPixelAlpha  {  //Alpha
                        print(pixelAddress)
                        return CGPoint(x: (pixelAddress / bytesPerpixel) % width, y: (pixelAddress / bytesPerpixel) / width)
                    }
                }
        }
        return nil
    }

    func firstUniquePixel( in image: UIImage) -> CGPoint?  {
        return pixelNotMatchingTopLeftColor(in: image, first: true)
    }

    func lastUniquePixel( in image: UIImage) -> CGPoint?  {
        return pixelNotMatchingTopLeftColor(in: image, first: false)
    }

You have to do something similar for left and right (if you have problems figuring out the pointer math then let me know). Then using top, left, bottom and right you just call CGImageCreateWithImageInRect.

Upvotes: 1

Related Questions