Skip to main content
 首页 » 操作系统

macos之在 OS X 上使用 Swift 混合两个 NSImages

2024年01月01日81mfrbuaa

我有两个 NSImage 实例。我希望 image2 放置在 image1 之上,具有一定的不透明度。它们具有匹配的尺寸。两个图像都不需要在 UI 中可见。

如何正确设置图形上下文并向其绘制图像,一个完全不透明,另一个半透明?

我在这里阅读了几个答案,但我发现它很复杂,尤其是因为大多数似乎是针对 Objective-C 或仅适用于 iOS 的。任何指针都适用。如果这可以在根本不需要 CGContext 的情况下完成,那就更好了。

func blendImages(image1: NSImage, image2: NSImage, alpha: CGFloat) -> CGImage { 
 
    // Create context 
    var ctx: CGContextRef = CGBitmapContextCreate(0, inputImage.size.width, inputImage.size.height, 8, inputImage.size.width*4, NSColorSpace.genericRGBColorSpace(), PremultipliedLast) 
    let area = CGRectMake(0, 0, inputImage.size.width, inputImage.size.height) 
    CGContextScaleCTM(ctx, 1, -1) 
 
    // Draw image1 in context 
 
    // Draw image2 with alpha opacity 
    CGContextSetAlpha(ctx, CGFloat(0.5)) 
 
    // Create CGImage from context 
    let outputImage = CGBitmapContextCreateImage(ctx) 
 
    return outputImage 
} 

在其他地方,我有这个扩展来从我的 NSImages 中获取 CGImages:

extension NSImage { 
    var CGImage: CGImageRef { 
        get { 
            let imageData = self.TIFFRepresentation 
            let source = CGImageSourceCreateWithData(imageData as! CFDataRef, nil) 
            let maskRef = CGImageSourceCreateImageAtIndex(source, 0, nil) 
            return maskRef 
        } 
    } 
} 

请您参考如下方法:

我设法用 NSGraphicsContext 解决了这个问题。

func mergeImagesAB(pathA: String, pathB: String, fraction: CGFloat) -> CGImage { 
 
    guard let imgA = NSImage(byReferencingFile: pathA), 
         let imgB = NSImage(byReferencingFile: pathB), 
         let bitmap = imgA.representations[0] as? NSBitmapImageRep, 
         let ctx = NSGraphicsContext(bitmapImageRep: bitmap) 
         else {fatalError("Failed to load images.")} 
 
    let rect = NSRect(origin: CGPoint(x: 0, y: 0), size: bitmap.size) 
 
    NSGraphicsContext.saveGraphicsState() 
    NSGraphicsContext.setCurrentContext(ctx) 
    imgB.drawInRect(rect, fromRect: rect, operation: .CompositeSourceOver, fraction: fraction) 
    NSGraphicsContext.restoreGraphicsState() 
 
    guard let result = bitmap.CGImage 
        else {fatalError("Failed to create image.")} 
 
    return result; 
}