// // NSImage+Extension.swift // PDF Reader Pro // // Created by Niehaoyu on 2024/10/23. // import Foundation extension NSImage { //MARK: - 修改图片颜色 func filled(with color: NSColor) -> NSImage? { let tintedImage = NSImage(size: self.size) tintedImage.lockFocus() let rect = NSRect(origin: .zero, size: self.size) color.setFill() rect.fill() self.draw(in: rect, from: NSZeroRect, operation: .destinationIn, fraction: 1.0) tintedImage.unlockFocus() return tintedImage } //MARK: - 组合图片 static func combineImages(images:[NSImage?]) -> NSImage? { var maxWidth: CGFloat = 0 var maxHeight: CGFloat = 0 for image in images { maxWidth = max(maxWidth, image!.size.width) maxHeight = max(maxHeight, image!.size.height) } let size = CGSize(width: maxWidth, height: maxHeight) let combinedImage = NSImage(size: size) combinedImage.lockFocus() for image in images { let rect = NSRect(origin: .zero, size: size) image!.draw(in: rect, from: rect, operation: .sourceOver, fraction: 1.0) } combinedImage.unlockFocus() return combinedImage } static func colorWithImage(baseImage: NSImage, frameImage: NSImage, withColor theColor: NSColor) -> NSImage { if let ciImage = CIImage(bitmapImageRep: NSBitmapImageRep(data: baseImage.tiffRepresentation!)!), let size = ciImage.extent.size as? CGSize { guard let ctx = CGContext(data: nil, width: Int(size.width * 4), height: Int(size.height * 4), bitsPerComponent: 8, bytesPerRow: 8 * Int(size.width * 4), space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else { return NSImage() } let red = UnsafeMutablePointer.allocate(capacity: 1) let green = UnsafeMutablePointer.allocate(capacity: 1) let blue = UnsafeMutablePointer.allocate(capacity: 1) let alpha = UnsafeMutablePointer.allocate(capacity: 1) let area = CGRect(x: 0, y: 0, width: size.width * 4, height: size.height * 4) ctx.saveGState() ctx.clip(to: area, mask: baseImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!) ctx.setFillColor(CGColor(red: red.pointee, green: green.pointee, blue: blue.pointee, alpha: alpha.pointee)) ctx.fill(area) ctx.restoreGState() ctx.setBlendMode(CGBlendMode.multiply) ctx.draw(baseImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!, in: area) ctx.draw(frameImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!, in: area) if let newImage = ctx.makeImage() { let image = NSImage(cgImage: newImage, size: size) return image } else { return NSImage() } } else { return NSImage() } } class func image(with size: NSSize, drawingHandler:((_ dstRect: NSRect) -> Bool)?) -> NSImage { var image = NSImage(size: size) image.lockFocus() if (drawingHandler != nil) { _ = drawingHandler!(NSMakeRect(0, 0, size.width, size.height)) } image.unlockFocus() return image } func pngData() -> Data? { guard let data = self.tiffRepresentation else { return nil } let imageRep = NSBitmapImageRep(data: data) imageRep?.size = self.size return imageRep?.representation(using: .png, properties: [:]) } func jpgData() -> Data? { guard let data = self.tiffRepresentation else { return nil } let imageRep = NSBitmapImageRep(data: data) imageRep?.size = self.size return imageRep?.representation(using: .jpeg, properties: [:]) } class func isDamageImage(_ image: NSImage?, imagePath path: String) -> Bool { let addImageAnnotation = (NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).last! as NSString).appendingPathComponent(Bundle.main.bundleIdentifier!) if !FileManager.default.fileExists(atPath: addImageAnnotation) { try? FileManager.default.createDirectory(atPath: addImageAnnotation, withIntermediateDirectories: false, attributes: nil) } let data = image?.tiffRepresentation let imageRep = NSBitmapImageRep(data: data!) imageRep?.size = image?.size ?? NSSize.zero var imageData: Data? if path.lowercased() == "png" { imageData = imageRep?.representation(using: .png, properties: [:]) } else { imageData = imageRep?.representation(using: .jpeg, properties: [:]) } let rPath = (addImageAnnotation as NSString).appendingPathComponent("waterAnnotation.png") if ((try? imageData?.write(to: URL(fileURLWithPath: rPath), options: .atomic)) == nil) { return true } else { return false } } }