Skip to content

Commit 5b368d3

Browse files
committed
[feat]: comparing images
1 parent fe7ddb9 commit 5b368d3

File tree

1 file changed

+67
-63
lines changed

1 file changed

+67
-63
lines changed

Sources/ScriptToolkit/NSImageExtension.swift

Lines changed: 67 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ import Foundation
99
import AppKit
1010

1111
public extension NSImage {
12-
12+
1313
/// Returns the height of the current image.
1414
var height: CGFloat {
1515
return self.size.height
1616
}
17-
17+
1818
/// Returns the width of the current image.
1919
var width: CGFloat {
2020
return self.size.width
2121
}
22-
22+
2323
var CGImage: CGImage {
2424
get {
2525
let imageData = self.tiffRepresentation!
@@ -30,14 +30,14 @@ public extension NSImage {
3030
}
3131

3232
/// Returns a png representation of the current image.
33-
var PNGRepresentation: Data? {
33+
var pngRepresentation: Data? {
3434
if let tiff = self.tiffRepresentation, let tiffData = NSBitmapImageRep(data: tiff) {
3535
return tiffData.representation(using: .png, properties: [:])
3636
}
37-
37+
3838
return nil
3939
}
40-
40+
4141
/// Copies the current image and resizes it to the given size.
4242
///
4343
/// - parameter size: The size of the new image.
@@ -46,76 +46,80 @@ public extension NSImage {
4646
func copy(size: NSSize) throws -> NSImage {
4747
// Create a new rect with given width and height
4848
let frame = NSMakeRect(0, 0, size.width, size.height)
49-
49+
5050
// Get the best representation for the given size.
5151
guard let rep = self.bestRepresentation(for: frame, context: nil, hints: nil) else {
5252
throw ScriptError.generalError(message: "Unable to resize image")
5353
}
54-
54+
5555
// Create an empty image with the given size.
5656
let img = NSImage(size: size)
57-
57+
5858
// Set the drawing context and make sure to remove the focus before returning.
5959
img.lockFocus()
6060
defer { img.unlockFocus() }
61-
61+
6262
// Draw the new image
6363
if rep.draw(in: frame) {
6464
return img
6565
}
66-
66+
6767
// Return nil in case something went wrong.
6868
throw ScriptError.generalError(message: "Unable to resize image")
6969
}
7070

71-
// func areImagesSame(firstPNGData: Data, secondPNGData: Data) -> Bool {
72-
// let sequence = Data([0x6C, 0x65, 0x58, 0x49, 0x66])
71+
func areImagesSame(leftImage: NSImage, rightImage: NSImage) -> Bool {
72+
guard let leftPNGData = leftImage.pngRepresentation, let rightPNGData = rightImage.pngRepresentation else { return false }
73+
74+
let sequence = Data([0x6C, 0x65, 0x58, 0x49, 0x66])
75+
76+
guard let leftOffset = leftPNGData.indexOf(data: sequence) else { return false }
77+
let leftSubdata = leftPNGData.subdata(in: leftOffset ..< leftPNGData.endIndex)
78+
79+
guard let rightOffset = rightPNGData.indexOf(data: sequence) else { return false }
80+
let rightSubdata = rightPNGData.subdata(in: rightOffset ..< rightPNGData.endIndex)
81+
82+
return leftSubdata == rightSubdata
83+
}
84+
85+
// func areImagesSame(leftImage: NSImage, rightImage: NSImage) -> Bool {
86+
// let width = Int(leftImage.size.width)
87+
// let height = Int(leftImage.size.height)
7388
//
74-
// guard let firstOffset = firstPNGData.indexOf(data: sequence) else { return false }
75-
// let firstSubdata = firstPNGData.subdata(in: firstOffset ..< firstPNGData.endIndex)
89+
// guard leftImage.size == rightImage.size else {
90+
// return false
91+
// }
92+
// var changes = 0
7693
//
77-
// guard let secondOffset = secondPNGData.indexOf(data: sequence) else { return false }
78-
// let secondSubdata = secondPNGData.subdata(in: secondOffset ..< secondPNGData.endIndex)
94+
// if let cfData1:CFData = leftImage.CGImage.dataProvider?.data,
95+
// let l = CFDataGetBytePtr(cfData1),
96+
// let cfData2:CFData = rightImage.CGImage.dataProvider?.data,
97+
// let r = CFDataGetBytePtr(cfData2) {
98+
// let bytesPerpixel = 4
99+
// let firstPixel = 0
100+
// let lastPixel = (width * height - 1) * bytesPerpixel
101+
// let range = stride(from: firstPixel, through: lastPixel, by: bytesPerpixel)
102+
// for pixelAddress in range {
103+
// if l.advanced(by: pixelAddress).pointee != r.advanced(by: pixelAddress).pointee || //Red
104+
// l.advanced(by: pixelAddress + 1).pointee != r.advanced(by: pixelAddress + 1).pointee || //Green
105+
// l.advanced(by: pixelAddress + 2).pointee != r.advanced(by: pixelAddress + 2).pointee || //Blue
106+
// l.advanced(by: pixelAddress + 3).pointee != r.advanced(by: pixelAddress + 3).pointee { //Alpha
107+
// changes += 1
108+
// }
109+
// }
110+
// }
79111
//
80-
// return firstSubdata == secondSubdata
112+
// return changes < 100
81113
// }
82114

83-
func areImagesSame(leftImage: NSImage, rightImage: NSImage) -> Bool {
84-
let width = Int(leftImage.size.width)
85-
let height = Int(leftImage.size.height)
86-
guard leftImage.size == rightImage.size else {
87-
return false
88-
}
89-
if let cfData1:CFData = leftImage.CGImage.dataProvider?.data,
90-
let l = CFDataGetBytePtr(cfData1),
91-
let cfData2:CFData = rightImage.CGImage.dataProvider?.data,
92-
let r = CFDataGetBytePtr(cfData2) {
93-
let bytesPerpixel = 4
94-
let firstPixel = 0
95-
let lastPixel = (width * height - 1) * bytesPerpixel
96-
let range = stride(from: firstPixel, through: lastPixel, by: bytesPerpixel)
97-
for pixelAddress in range {
98-
if l.advanced(by: pixelAddress).pointee != r.advanced(by: pixelAddress).pointee || //Red
99-
l.advanced(by: pixelAddress + 1).pointee != r.advanced(by: pixelAddress + 1).pointee || //Green
100-
l.advanced(by: pixelAddress + 2).pointee != r.advanced(by: pixelAddress + 2).pointee || //Blue
101-
l.advanced(by: pixelAddress + 3).pointee != r.advanced(by: pixelAddress + 3).pointee { //Alpha
102-
print(pixelAddress)
103-
104-
return false
105-
}
106-
}
107-
}
108-
109-
return true
110-
}
111-
112115
/// Saves the PNG representation of the current image to the HD.
113116
///
114117
/// - parameter url: The location url to which to write the png file.
115118
func savePNGRepresentationToURL(url: URL, onlyChange: Bool = true) throws {
116-
if let pngData = self.PNGRepresentation {
119+
if let pngData = self.pngRepresentation {
117120
if let originalImage = NSImage(contentsOf: url) {
118121
if onlyChange && areImagesSame(leftImage: self, rightImage: originalImage) {
122+
print(" Keeping original file - no change")
119123
return
120124
}
121125
}
@@ -135,22 +139,22 @@ public extension NSImage {
135139
else {
136140
throw ScriptError.generalError(message: "Image processing error")
137141
}
138-
142+
139143
let filter = CIFilter(name: "CISourceOverCompositing")!
140144
filter.setDefaults()
141-
145+
142146
filter.setValue(firstImage, forKey: "inputImage")
143147
filter.setValue(secondImage, forKey: "inputBackgroundImage")
144-
148+
145149
let resultImage = filter.outputImage
146-
150+
147151
let rep = NSCIImageRep(ciImage: resultImage!)
148152
let finalResult = NSImage(size: rep.size)
149153
finalResult.addRepresentation(rep)
150-
154+
151155
return finalResult
152156
}
153-
157+
154158
/// Image annotation
155159
func image(
156160
withText text: String,
@@ -162,7 +166,7 @@ public extension NSImage {
162166
let image = self
163167
let text = text as NSString
164168
let options: NSString.DrawingOptions = [.usesLineFragmentOrigin, .usesFontLeading]
165-
169+
166170
let textSize = text.boundingRect(with: image.size, options: options, attributes: attributes).size
167171
var offsetX: CGFloat
168172

@@ -176,16 +180,16 @@ public extension NSImage {
176180
default:
177181
offsetX = 0
178182
}
179-
183+
180184
let point = NSMakePoint(image.size.width * horizontalTitlePosition + offsetX, image.size.height * verticalTitlePosition - textSize.height/2)
181-
185+
182186
image.lockFocus()
183187
text.draw(at: point, withAttributes: attributes)
184188
image.unlockFocus()
185-
189+
186190
return image
187191
}
188-
192+
189193
/// Image annotation
190194
func annotate(
191195
text: String,
@@ -198,9 +202,9 @@ public extension NSImage {
198202
stroke: NSColor,
199203
strokeWidth: CGFloat
200204
) throws -> NSImage {
201-
205+
202206
guard let titleFont = NSFont(name: font, size: size) else { throw ScriptError.argumentError(message: "Unable to find font \(font)") }
203-
207+
204208
var alignmentMode: NSTextAlignment
205209

206210
switch titleAlignment {
@@ -228,8 +232,8 @@ public extension NSImage {
228232
],
229233
horizontalTitlePosition: horizontalTitlePosition,
230234
verticalTitlePosition: verticalTitlePosition
231-
)
232-
235+
)
236+
233237
// Add strokes
234238
return fillText.image(
235239
withText: text,

0 commit comments

Comments
 (0)