@@ -9,17 +9,17 @@ import Foundation
99import AppKit
1010
1111public 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