basic bitmap storage
Useful for comparing two JPEG images saved with a different compression ratios.

You can use these pictures for testing (use the full-size version of each):



50% quality JPEG

100% quality JPEG







link to full size 50% image

link to full size 100% image

The expected difference for these two images is 1.62125%

func pixelValues(fromCGImage imageRef: CGImage?) -> [UInt8]?
{
    var width = 0
    var height = 0
    var pixelValues: [UInt8]?
 
    if let imageRef = imageRef {
        width = imageRef.width
        height = imageRef.height
        let bitsPerComponent = imageRef.bitsPerComponent
        let bytesPerRow = imageRef.bytesPerRow
        let totalBytes = height * bytesPerRow
        let bitmapInfo = imageRef.bitmapInfo
 
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        var intensities = [UInt8](repeating: 0, count: totalBytes)
 
        let contextRef = CGContext(data: &intensities,
                                  width: width,
                                 height: height,
                       bitsPerComponent: bitsPerComponent,
                            bytesPerRow: bytesPerRow,
                                  space: colorSpace,
                             bitmapInfo: bitmapInfo.rawValue)
        contextRef?.draw(imageRef, in: CGRect(x: 0.0, y: 0.0, width: CGFloat(width), height: CGFloat(height)))
 
        pixelValues = intensities
    }
 
    return pixelValues
}
 
func compareImages(image1: UIImage, image2: UIImage) -> Double? {
    guard let data1 = pixelValues(fromCGImage: image1.cgImage),
        let data2 = pixelValues(fromCGImage: image2.cgImage),
        data1.count == data2.count else {
            return nil
    }
 
    let width = Double(image1.size.width)
    let height = Double(image1.size.height)
 
    return zip(data1, data2)
        .enumerated()
        .reduce(0.0) {
            $1.offset % 4 == 3 ? $0 : $0 + abs(Double($1.element.0) - Double($1.element.1))
        }
        * 100 / (width * height * 3.0) / 255.0
}
 
let image1 = UIImage(named: "Lenna50")
let image2 = UIImage(named: "Lenna100")
 
compareImages(image1: image1, image2: image2)
 
 