绘制标准 NSImage 反转(白色而不是黑色)
我正在尝试用白色而不是黑色绘制标准 NSImage。以下方法可以很好地在当前 NSGraphicsContext 中绘制黑色图像:
NSImage* image = [NSImage imageNamed:NSImageNameEnterFullScreenTemplate];
[image drawInRect:r fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
我希望 NSCompositeXOR 能够实现这一目的,但没有。我需要走复杂的 [CIFilter filterWithName:@"CIColorInvert"] 路径吗?我觉得我一定错过了一些简单的东西。
I'm trying to draw a standard NSImage in white instead of black. The following works fine for drawing the image in black in the current NSGraphicsContext:
NSImage* image = [NSImage imageNamed:NSImageNameEnterFullScreenTemplate];
[image drawInRect:r fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
I expected NSCompositeXOR to do the trick, but no. Do I need to go down the complicated [CIFilter filterWithName:@"CIColorInvert"] path? I feel like I must be missing something simple.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Core Image 路线是最可靠的。其实并不复杂,我在下面发布了一个示例。如果您知道您的图像不会被翻转,那么您可以删除转换代码。主要要注意的是,从
NSImage
到CIImage
的转换在性能方面可能会很昂贵,因此您应该确保缓存CIImage
> 如果可能的话,不要在每次绘图操作期间重新创建它。注意:释放/保留内存管理留作练习,上面的代码假设垃圾收集。
如果你想以任意大小渲染图像,你可以执行以下操作:
The Core Image route would be the most reliable. It's actually not very complicated, I've posted a sample below. If you know none of your images will be flipped then you can remove the transform code. The main thing to be careful of is that the conversion from
NSImage
toCIImage
can be expensive performance-wise, so you should ensure you cache theCIImage
if possible and don't re-create it during each drawing operation.Note: release/retain memory management is left as an exercise, the code above assumes garbage collection.
If you want to render the image at an arbitrary size, you could do the following:
这是一个使用 Swift 5.1 的解决方案,有点基于上述解决方案。请注意,我没有缓存图像,因此它可能不是最有效的,因为我的主要用例是根据当前配色方案是浅色还是深色来翻转工具栏按钮中的小单色图像。
Here is a solution using Swift 5.1, somewhat based on the above solutions. Note that I am not cacheing the images, so it likely isn't the most efficient as my primary use case is to flip small monochrome images in toolbar buttons based on whether the current color scheme is light or dark.
请注意:我发现 CIColorInvert 过滤器并不总是可靠。例如,如果您想反转 Photoshop 中反转的图像,CIFilter 将生成更亮的图像。据我了解,发生这种情况是因为 CIFilter 的伽玛值(伽玛为 1)和来自其他来源的图像存在差异。
当我在寻找更改 CIFilter 的 gamma 值的方法时,我发现了一个注释,指出 CIContext 中存在一个错误:更改其默认的 1 的 gamma 值将产生不可预测的结果。
无论如何,还有另一种反转 NSImage 的解决方案,它总是产生正确的结果 - 通过反转 NSBitmapImageRep 的像素。
我重新发布来自 etutorials.org 的代码 (http://bit.ly/Y6GpLn):
Just one note: I found that CIColorInvert filter isn't always reliable. For example, if you want to invert back an image inverted in Photoshop, the CIFilter will produce a much lighter image. As far as I understood, it happens because of the differences in gamma value of CIFilter (gamma is 1) and images that came from other sources.
While I was looking for ways to change the gamma value for CIFilter, I found a note that there's a bug in CIContext: changing its gamma value from the default 1 will produce unpredictable results.
Regardless, there's another solution to invert NSImage, which always produces the correct results - by inverting pixels of NSBitmapImageRep.
I'm reposting the code from etutorials.org (http://bit.ly/Y6GpLn):