marinofaggiana 3 жил өмнө
parent
commit
ee3f3c6ccd

+ 7 - 0
iOSClient/Extensions/UIImage+Extensions.swift

@@ -151,4 +151,11 @@ extension UIImage {
             }
         }
     }
+    
+    func isEqualToImage(image: UIImage?) -> Bool {
+        if image == nil { return false }
+        let data1: NSData = self.pngData()! as NSData
+        let data2: NSData = image!.pngData()! as NSData
+        return data1.isEqual(data2)
+    }
 }

+ 13 - 2
iOSClient/Networking/NCService.swift

@@ -107,10 +107,21 @@ class NCService: NSObject {
                     self.synchronizeOffline(account: tableAccount.account)
                     
                     // Get Avatar
-                    //let avatarUrl = "\(self.appDelegate.urlBase)/index.php/avatar/\(self.appDelegate.user)/\(NCGlobal.shared.avatarSize)".addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!
                     let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + stringUser + "-" + self.appDelegate.user + ".png"
+                    let oldData = try? Data(contentsOf: URL(fileURLWithPath: fileNameLocalPath))
                     NCCommunication.shared.downloadAvatar(user: user, fileNameLocalPath: fileNameLocalPath, size: NCGlobal.shared.avatarSize) { (account, data, errorCode, errorMessage) in
-                        NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadAvatar, userInfo: nil)
+                        if let data = data, let oldData = oldData {
+                            do {
+                                let isEqual = try NCUtility.shared.compare(tolerance: 95, expected: data, observed: oldData)
+                                if !isEqual {
+                                    NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadAvatar, userInfo: nil)
+                                }
+                            } catch {
+                                NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadAvatar, userInfo: nil)
+                            }
+                        } else {
+                            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadAvatar, userInfo: nil)
+                        }
                     }
                     self.requestServerCapabilities()
                 }

+ 80 - 0
iOSClient/Utility/NCUtility.swift

@@ -607,6 +607,86 @@ class NCUtility: NSObject {
             self.viewBackgroundActivityIndicator = nil
         }
     }
+    
+    func compare(tolerance: Float, expected: Data, observed: Data) throws -> Bool {
+        
+        enum customError: Error {
+            case unableToGetUIImageFromData
+            case unableToGetCGImageFromData
+            case unableToGetColorSpaceFromCGImage
+            case imagesHasDifferentSizes
+            case unableToInitializeContext
+        }
+        
+        guard let expectedUIImage = UIImage(data: expected), let observedUIImage = UIImage(data: observed) else {
+            throw customError.unableToGetUIImageFromData
+        }
+        guard let expectedCGImage = expectedUIImage.cgImage, let observedCGImage = observedUIImage.cgImage else {
+            throw customError.unableToGetCGImageFromData
+        }
+        guard let expectedColorSpace = expectedCGImage.colorSpace, let observedColorSpace = observedCGImage.colorSpace else {
+            throw customError.unableToGetColorSpaceFromCGImage
+        }
+        if expectedCGImage.width != observedCGImage.width || expectedCGImage.height != observedCGImage.height {
+            throw customError.imagesHasDifferentSizes
+        }
+        let imageSize = CGSize(width: expectedCGImage.width, height: expectedCGImage.height)
+        let numberOfPixels = Int(imageSize.width * imageSize.height)
+
+        // Checking that our `UInt32` buffer has same number of bytes as image has.
+        let bytesPerRow = min(expectedCGImage.bytesPerRow, observedCGImage.bytesPerRow)
+        assert(MemoryLayout<UInt32>.stride == bytesPerRow / Int(imageSize.width))
+
+        let expectedPixels = UnsafeMutablePointer<UInt32>.allocate(capacity: numberOfPixels)
+        let observedPixels = UnsafeMutablePointer<UInt32>.allocate(capacity: numberOfPixels)
+
+        let expectedPixelsRaw = UnsafeMutableRawPointer(expectedPixels)
+        let observedPixelsRaw = UnsafeMutableRawPointer(observedPixels)
+
+        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
+        guard let expectedContext = CGContext(data: expectedPixelsRaw, width: Int(imageSize.width), height: Int(imageSize.height),
+                                              bitsPerComponent: expectedCGImage.bitsPerComponent, bytesPerRow: bytesPerRow,
+                                              space: expectedColorSpace, bitmapInfo: bitmapInfo.rawValue) else {
+            expectedPixels.deallocate()
+            observedPixels.deallocate()
+            throw customError.unableToInitializeContext
+        }
+        guard let observedContext = CGContext(data: observedPixelsRaw, width: Int(imageSize.width), height: Int(imageSize.height),
+                                              bitsPerComponent: observedCGImage.bitsPerComponent, bytesPerRow: bytesPerRow,
+                                              space: observedColorSpace, bitmapInfo: bitmapInfo.rawValue) else {
+            expectedPixels.deallocate()
+            observedPixels.deallocate()
+            throw customError.unableToInitializeContext
+        }
+
+        expectedContext.draw(expectedCGImage, in: CGRect(origin: .zero, size: imageSize))
+        observedContext.draw(observedCGImage, in: CGRect(origin: .zero, size: imageSize))
+
+        let expectedBuffer = UnsafeBufferPointer(start: expectedPixels, count: numberOfPixels)
+        let observedBuffer = UnsafeBufferPointer(start: observedPixels, count: numberOfPixels)
+
+        var isEqual = true
+        if tolerance == 0 {
+            isEqual = expectedBuffer.elementsEqual(observedBuffer)
+        } else {
+            // Go through each pixel in turn and see if it is different
+            var numDiffPixels = 0
+            for pixel in 0 ..< numberOfPixels where expectedBuffer[pixel] != observedBuffer[pixel] {
+                // If this pixel is different, increment the pixel diff count and see if we have hit our limit.
+                numDiffPixels += 1
+                let percentage = 100 * Float(numDiffPixels) / Float(numberOfPixels)
+                if percentage > tolerance {
+                    isEqual = false
+                    break
+                }
+            }
+        }
+
+        expectedPixels.deallocate()
+        observedPixels.deallocate()
+
+        return isEqual
+    }
 }
 
 // MARK: -