From 7c8b8ff422cc6e09138f8a0371404ae75b652b0c Mon Sep 17 00:00:00 2001 From: Christoffer Winterkvist Date: Wed, 21 Apr 2021 10:35:47 +0200 Subject: [PATCH] Apply fix from https://github.com/pointfreeco/swift-snapshot-testing/pull/446 Credit to @dflems --- .../Snapshotting/UIImage.swift | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/Sources/SnapshotTesting/Snapshotting/UIImage.swift b/Sources/SnapshotTesting/Snapshotting/UIImage.swift index 318b107ee..6c328d76f 100644 --- a/Sources/SnapshotTesting/Snapshotting/UIImage.swift +++ b/Sources/SnapshotTesting/Snapshotting/UIImage.swift @@ -32,8 +32,8 @@ extension Diffing where Value == UIImage { ) } } - - + + /// Used when the image size has no width or no height to generated the default empty image private static func emptyImage() -> UIImage { let label = UILabel(frame: CGRect(x: 0, y: 0, width: 400, height: 80)) @@ -62,6 +62,11 @@ extension Snapshotting where Value == UIImage, Format == UIImage { } } +// remap snapshot & reference to same colorspace + let imageContextColorSpace = CGColorSpace(name: CGColorSpace.sRGB) + let imageContextBitsPerComponent = 8 + let imageContextBytesPerPixel = 4 + private func compare(_ old: UIImage, _ new: UIImage, precision: Float) -> Bool { guard let oldCgImage = old.cgImage else { return false } guard let newCgImage = new.cgImage else { return false } @@ -71,23 +76,18 @@ private func compare(_ old: UIImage, _ new: UIImage, precision: Float) -> Bool { guard oldCgImage.height != 0 else { return false } guard newCgImage.height != 0 else { return false } guard oldCgImage.height == newCgImage.height else { return false } - // Values between images may differ due to padding to multiple of 64 bytes per row, - // because of that a freshly taken view snapshot may differ from one stored as PNG. - // At this point we're sure that size of both images is the same, so we can go with minimal `bytesPerRow` value - // and use it to create contexts. - let minBytesPerRow = min(oldCgImage.bytesPerRow, newCgImage.bytesPerRow) - let byteCount = minBytesPerRow * oldCgImage.height + let byteCount = imageContextBytesPerPixel * oldCgImage.width * oldCgImage.height var oldBytes = [UInt8](repeating: 0, count: byteCount) - guard let oldContext = context(for: oldCgImage, bytesPerRow: minBytesPerRow, data: &oldBytes) else { return false } + guard let oldContext = context(for: oldCgImage, data: &oldBytes) else { return false } guard let oldData = oldContext.data else { return false } - if let newContext = context(for: newCgImage, bytesPerRow: minBytesPerRow), let newData = newContext.data { + if let newContext = context(for: newCgImage), let newData = newContext.data { if memcmp(oldData, newData, byteCount) == 0 { return true } } let newer = UIImage(data: new.pngData()!)! guard let newerCgImage = newer.cgImage else { return false } var newerBytes = [UInt8](repeating: 0, count: byteCount) - guard let newerContext = context(for: newerCgImage, bytesPerRow: minBytesPerRow, data: &newerBytes) else { return false } + guard let newerContext = context(for: newerCgImage, data: &newerBytes) else { return false } guard let newerData = newerContext.data else { return false } if memcmp(oldData, newerData, byteCount) == 0 { return true } if precision >= 1 { return false } @@ -100,16 +100,17 @@ private func compare(_ old: UIImage, _ new: UIImage, precision: Float) -> Bool { return true } -private func context(for cgImage: CGImage, bytesPerRow: Int, data: UnsafeMutableRawPointer? = nil) -> CGContext? { +private func context(for cgImage: CGImage, data: UnsafeMutableRawPointer? = nil) -> CGContext? { + let bytesPerRow = cgImage.width * imageContextBytesPerPixel guard - let space = cgImage.colorSpace, + let colorSpace = imageContextColorSpace, let context = CGContext( data: data, width: cgImage.width, height: cgImage.height, - bitsPerComponent: cgImage.bitsPerComponent, + bitsPerComponent: imageContextBitsPerComponent, bytesPerRow: bytesPerRow, - space: space, + space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue ) else { return nil }