12

我有一个 CGImageRef(我们称之为原始图像)和一个透明的 png(水印)。我正在尝试编写一种方法来将水印放在原件之上,并返回一个 CGImageRef。

在 iOS 中,我会使用 UIKit 将它们都绘制到上下文中,但对于 OSX(不支持 UIKit)来说,这似乎是不可能的。

堆叠两个图像的最简单方法是什么?谢谢

4

3 回答 3

14

对于一个快速的'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。

于 2013-09-03T04:25:48.727 回答
5

当您渲染到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 是您工作的一个不错选择。

于 2013-09-03T07:10:18.300 回答
4

如果有人像我一样需要 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 示例做同样的事情。

于 2020-06-06T04:00:54.760 回答