我有一个 CGImageRef(我们称之为原始图像)和一个透明的 png(水印)。我正在尝试编写一种方法来将水印放在原件之上,并返回一个 CGImageRef。
在 iOS 中,我会使用 UIKit 将它们都绘制到上下文中,但对于 OSX(不支持 UIKit)来说,这似乎是不可能的。
堆叠两个图像的最简单方法是什么?谢谢
我有一个 CGImageRef(我们称之为原始图像)和一个透明的 png(水印)。我正在尝试编写一种方法来将水印放在原件之上,并返回一个 CGImageRef。
在 iOS 中,我会使用 UIKit 将它们都绘制到上下文中,但对于 OSX(不支持 UIKit)来说,这似乎是不可能的。
堆叠两个图像的最简单方法是什么?谢谢
对于一个快速的'n脏解决方案,您可以使用 NSImage 绘图 API:
NSImage *background = [NSImage imageNamed:@"background"];
NSImage *overlay = [NSImage imageNamed:@"overlay"];
NSImage *newImage = [[NSImage alloc] initWithSize:[background size]];
[newImage lockFocus];
CGRect newImageRect = CGRectZero;
newImageRect.size = [newImage size];
[background drawInRect:newImageRect];
[overlay drawInRect:newImageRect];
[newImage unlockFocus];
CGImageRef newImageRef = [newImage CGImageForProposedRect:NULL context:nil hints:nil];
如果您不喜欢这样,您期望的大多数 CGContext API 都可以跨平台使用 — 用于通过更多控制进行绘图。同样,您可以查看 NSGraphicsContext。
当您渲染到CGContext
.
如果您想要图像作为结果,您可以创建并渲染到 a CGBitmapContext
,然后在渲染后请求图像。
一般流程,省略了常见细节和上下文信息:
CGImageRef CreateCompositeOfImages(CGImageRef pBackground,
const CGRect pBackgroundRect,
CGImageRef pForeground,
const CGRect pForegroundRect)
{
// configure context parameters
CGContextRef gtx = CGBitmapContextCreate( %%% );
// configure context
// configure context to render background image
// draw background image
CGContextDrawImage(gtx, pBackgroundRect, pBackground);
// configure context to render foreground image
// draw foreground image
CGContextDrawImage(gtx, pForegroundRect, pForeground);
// create result
CGImageRef result = CGBitmapContextCreateImage(gtx);
// cleanup
return result;
}
您需要从您的 PNG 创建一个 CGImage。
您可能有兴趣使用的其他 API:
CGContextSetBlendMode
CGContextSetAllowsAntialiasing
CGContextSetInterpolationQuality
.我知道很多人通常会建议您使用更高级别的抽象(即 AppKit 和 UIKit),但 CoreGraphics 是一个很棒的库,可以在这两种情况下进行渲染。如果您对在 OS X 和 iOS 中都易于使用的图形实现感兴趣,如果您对这些抽象工作感到满意,CoreGraphics 是您工作的一个不错选择。
如果有人像我一样需要 Swift 版本。
这是一个功能性的 Swift 5 版本:
let background = NSImage(named: "background")
let overlay = NSImage(named: "overlay")
let newImage = NSImage(size: background.size)
newImage.lockFocus()
var newImageRect: CGRect = .zero
newImageRect.size = newImage.size
background.draw(in: newImageRect)
overlay.draw(in: newImageRect)
newImage.unlockFocus()
我希望我有时间对 CGContext 示例做同样的事情。