-
Notifications
You must be signed in to change notification settings - Fork 7
/
ImposterChecker.swift
105 lines (81 loc) · 3.44 KB
/
ImposterChecker.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//
// ImposterChecker.swift
// Nostur
//
// Created by Fabian Lachman on 19/07/2023.
//
import SwiftUI
func compareImages(image1: UIImage, image2: UIImage) -> CGFloat {
guard let cgImage1 = image1.cgImage, let cgImage2 = image2.cgImage,
let data1 = cgImage1.dataProvider?.data as Data?,
let data2 = cgImage2.dataProvider?.data as Data? else {
return 1.0
}
let pixelCount = Int(image1.size.width * image1.size.height)
let pixelData1 = [UInt8](data1)
let pixelData2 = [UInt8](data2)
var mae: CGFloat = 0.0
for i in stride(from: 0, to: pixelCount * 4, by: 4) {
guard i+2 < pixelData1.count, i+2 < pixelData2.count else { continue }
let r1 = CGFloat(pixelData1[i])
let g1 = CGFloat(pixelData1[i + 1])
let b1 = CGFloat(pixelData1[i + 2])
if i < pixelData2.count {
let r2 = CGFloat(pixelData2[i])
let g2 = CGFloat(pixelData2[i + 1])
let b2 = CGFloat(pixelData2[i + 2])
let diffR = abs(r1 - r2)
let diffG = abs(g1 - g2)
let diffB = abs(b1 - b2)
let diff = (diffR + diffG + diffB) / (3 * 255)
mae += diff
}
}
mae /= CGFloat(pixelCount)
return mae
}
func pfpsAreSimilar(imposter:URL, real:URL, threshold:Double = 0.1) async -> Bool {
guard imposter != real else { return true } // if urls are the same we don't need to check the actual images
var impostorImage:UIImage?
var realImage:UIImage?
let impostorReq = pfpImageRequestFor(imposter, size: DIMENSIONS.POST_ROW_PFP_DIAMETER)
let realReq = pfpImageRequestFor(real, size: DIMENSIONS.POST_ROW_PFP_DIAMETER)
let task1 = ImageProcessing.shared.pfp.imageTask(with: impostorReq)
if let response = try? await task1.response {
impostorImage = response.container.image //.preparingForDisplay()
}
let task2 = ImageProcessing.shared.pfp.imageTask(with: realReq)
if let response = try? await task2.response {
realImage = response.container.image //.preparingForDisplay()
}
guard let impostorImage = impostorImage, let realImage = realImage else { return false }
let mae = compareImages(image1: impostorImage, image2: realImage)
L.og.debug("😎 ImposterChecker - imagesAreSimilar: \(mae)")
// print("😎 ImposterChecker - imagesAreSimilar: \(mae)")
if (mae == 0.0) { return false }
if mae <= threshold {
return true
} else {
return false
}
}
struct ImposterTesterView: View {
var body: some View {
Text(verbatim: "test1")
.task {
let imposter = "https://cdn.nostr.build/i/eb8d33b383e103c1143a040dda69729d19e8e3115735c3ef3a283b08723b0a6c.jpg"
let real = "https://nostr.build/i/p/nostr.build_6b9909bccf0f4fdaf7aacd9bc01e4ce70dab86f7d90395f2ce925e6ea06ed7cd.jpeg"
let similar = await pfpsAreSimilar(imposter: URL(string: imposter)!, real: URL(string: real)!)
print("are they similar: \(similar)")
}
}
}
struct Previews_ImpostorChecker_Previews: PreviewProvider {
static var previews: some View {
ImposterTesterView()
.previewDevice(PreviewDevice(rawValue: PREVIEW_DEVICE))
}
}
func isSimilar(string1: String, string2: String, percent:Double = 0.95) -> Bool {
return string1.distance(between: string2) >= percent
}