Skip to content

Commit

Permalink
Optimize compareImages(with:tolerance:) function
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor Peschenkov committed May 2, 2020
1 parent 3e6dc17 commit d6c2ca7
Showing 1 changed file with 37 additions and 27 deletions.
64 changes: 37 additions & 27 deletions LetterAvatarKitTests/Utilities/UIImage+Compare.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ extension UIImage {
guard let image = object as? UIImage else {
return false
}
return compare(with: image, tolerance: 0.01)
return compareImages(with: image, tolerance: 0.01)
}

open func compare(with image: UIImage?, tolerance: CGFloat) -> Bool {
open func compareImages(with image: UIImage?, tolerance: CGFloat) -> Bool {
guard let image = image else {
return false
}
Expand All @@ -57,47 +57,57 @@ extension UIImage {
return false
}

var lhsImage: UIImage?
UIGraphicsBeginImageContext(size)
if UIGraphicsGetCurrentContext() != nil {
self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
lhsImage = UIGraphicsGetImageFromCurrentImageContext()
var lhsImage: CGImage? = self.cgImage
var rhsImage: CGImage? = image.cgImage
let convertToSuitableByteOrder = { (image: UIImage, size: CGSize) -> CGImage? in
defer {
UIGraphicsEndImageContext()
}
UIGraphicsBeginImageContext(size)
if UIGraphicsGetCurrentContext() != nil {
image.draw(in: CGRect(
x: 0,
y: 0,
width: size.width,
height: size.height
))
return UIGraphicsGetImageFromCurrentImageContext()?.cgImage
}
return nil
}
UIGraphicsEndImageContext()

var rhsImage: UIImage?
UIGraphicsBeginImageContext(size)
if UIGraphicsGetCurrentContext() != nil {
image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
rhsImage = UIGraphicsGetImageFromCurrentImageContext()
if #available(iOS 12.0, *) {
if lhsImage?.byteOrderInfo != rhsImage?.byteOrderInfo {
lhsImage = convertToSuitableByteOrder(self, self.size)
rhsImage = convertToSuitableByteOrder(image, image.size)
}
} else {
lhsImage = convertToSuitableByteOrder(self, self.size)
rhsImage = convertToSuitableByteOrder(image, image.size)
}
UIGraphicsEndImageContext()

guard let lhs = lhsImage?.cgImage, let rhs = rhsImage?.cgImage else {
guard let lhs = lhsImage, let rhs = rhsImage else {
return false
}

guard let lhsData = lhs.dataProvider?.data, let rhsData = rhs.dataProvider?.data else {
return false
guard let lhsData = lhs.dataProvider?.data,
let rhsData = rhs.dataProvider?.data else {
return false
}

if lhsData == rhsData {
return true
} else {
guard let lhsPixelsPointer: UnsafePointer<UInt8> = CFDataGetBytePtr(lhsData) else {
return false
}

guard let rhsPixelsPointer: UnsafePointer<UInt8> = CFDataGetBytePtr(rhsData) else {
return false
guard let lhsPixelsPointer: UnsafePointer<UInt8> = CFDataGetBytePtr(lhsData),
let rhsPixelsPointer: UnsafePointer<UInt8> = CFDataGetBytePtr(rhsData) else {
return false
}

var diff = 0
var errorCount = 0
let numberOfPixels = Int(self.size.width * self.size.height * 4)
for i in stride(from: 0, to: numberOfPixels, by: 1) {
if lhsPixelsPointer[i] != rhsPixelsPointer[i] {
diff += 1
let error = CGFloat(CGFloat(diff) / CGFloat(numberOfPixels))
errorCount += 1
let error = CGFloat(CGFloat(errorCount) / CGFloat(numberOfPixels))
if error > tolerance {
return false
}
Expand Down

0 comments on commit d6c2ca7

Please sign in to comment.