问题标签 [nsimage]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1318 浏览

cocoa - 绘制透明 NSImage 使所有 NSView 透明

我在 Cocoa 应用程序中有三个 NSView,每个子视图都是另一个。

FirstNSView -> SecondNSView -> ThirdNSView

FirstNSView 使用核心图形绘制纯色背景填充。

SecondNSView 是许多其他视图的容器视图。

ThirdNSView 使用以下代码将 NSImage 绘制到其框架中drawRect

[img drawAtPoint:NSMakePoint(0, 0) fromRect:NSMakeRect(0, 0, img.size.width, img.size.height) operation:NSCompositeDestinationAtop fraction:1.0];

我使用它是NSCompositeDestinationAtop因为它允许图像几乎充当img.

但是,透明区域img使整个窗口透明,而不是像我期望的那样显示到 FirstNSView。像这样:

在此处输入图像描述

请注意,尝试使用其他复合类型仍然会导致同样的问题。

我已经阅读了很多关于 NSViews 不是用于“分层”的信息,但我不确定这是否与此处相关。到目前为止,我一直在使用 Core Graphics 在 NSView 上进行很好的绘图,并且透明部分暴露了“后面”的层。只有在尝试合成此图像时才会出现此问题。

我很感激任何关于为什么会发生这种情况以及解决它的可能方法的指示。

0 投票
1 回答
1228 浏览

cocoa - 使用 NSImage 创建和编写调色板 RGBA PNG

我正在尝试使用 Cocoa 框架*创建使用 RGBA 调色板(每个调色板条目 32 位)的调色板PNG 图像(每像素 8 位)。

我尝试了几种[NSBitmapImageRep initWithBitmapDataPlanes:…]方法组合。它似乎为bitsPerSample:2 bitsPerPixel:8.

然而,当我尝试用我写这样的位图时,[NSBitmapImageRep representationUsingType:NSPNGFileType…]我得到:

如果我尝试其他位深度,那么我会得到每像素 32 位(非调色板)图像。


*)我知道我可以使用libpng,但这不是我正在寻找的答案。

0 投票
4 回答
4676 浏览

opengl - 如何从 ARGB NSImage 加载 OpenGL 纹理而不进行混杂?

我正在为 Mac OS >= 10.6 编写一个应用程序,它从磁盘加载的图像创建 OpenGL 纹理。

首先,我将图像加载到 NSImage 中。然后我从图像中获取 NSBitmapImageRep 并使用 glTexImage2D 将像素数据加载到纹理中。

对于 RGB 或 RGBA 图像,它可以完美运行。我可以传入 3 字节/像素的 RGB 或 4 字节的 RGBA,并创建一个 4 字节/像素的 RGBA 纹理。

然而,我刚刚让一个测试员给我发了一张似乎有 ARGB 字节顺序的 JPEG 图像(在佳能 EOS 50D 上拍摄,不确定它是如何导入的)。

我在这个线程上找到了一个帖子:(http://www.cocoabuilder.com/archive/cocoa/12782-coregraphics-over-opengl.html)这表明我将GL_BGRA的格式参数指定为glTexImage2D,并且类型为GL_UNSIGNED_INT_8_8_8_8_REV。

这似乎合乎逻辑,并且似乎应该有效,但事实并非如此。我得到不同但仍然错误的颜色值。

我编写了“swizzling”(手动字节交换)代码,将 ARGB 图像数据洗牌到一个新的 RGBA 缓冲区中,但是这种逐字节的混合对于大图像来说会很慢。

我也想了解如何使这项工作“以正确的方式”。

将 ARGB 数据加载到 RGBA OpenGL 纹理中的技巧是什么?

我当前对 xxx 的调用如下所示:

其中是 RGB 或 RGBA。

我尝试使用:

当我的图像代表报告它是“alpha first”顺序时。

作为第二个问题,我还读到大多数显卡的“本机”格式是 GL_BGRA,因此以该格式创建纹理会导致更快的纹理绘制。纹理绘制的速度比加载纹理的速度更重要,因此预先将数据“混合”为 BGRA 格式是值得的。我尝试通过指定 GL_RGBA 的“内部格式”来要求 OpenGL 创建 BGRA 纹理,但这会导致图像完全变黑。我对文档的解释使我期望 glTexImage2D 会在读取数据时对数据进行字节交换,如果源格式和内部格式不同,但是当我尝试指定“内部格式”时,我得到一个 OpenGL 错误 0x500 (GL_INVALID_ENUM) GL_RGBA。我错过了什么?

0 投票
1 回答
2043 浏览

cocoa - 加载和释放 NSImage 时内存继续增加

我有一个问题,即我的应用程序通过连续的图像文件加载将内存大量消耗到“颠簸点”。例如,考虑以下代码,它重复加载和释放 15MB JPEG 文件(用于测试的大文件):

由于有大量可用的系统内存,它在前几个中执行得很快,但最终系统在我所说的“临界点”处屈服。在这里,我相信系统释放的内存刚好足以加载下一张图像,因此性能最终会变慢。此外,现在其他应用程序运行缓慢,因为系统必须释放这些占用但现在未使用的内存。

对我来说有意义的是,它是否会分配内存然后让系统释放它,以便我在 Activity Monitor 中的“Real Mem”统计保持较小,而不是通过连续的加载/释放迭代进入千兆字节。在实践中,我可能永远不会在这一点上结束,但是当任何时候所需的实际常驻内存通常很小时,我的活动监视器“Real Mem”统计数据最终超过所有其他应用程序似乎很奇怪。我最初认为这是某种内存泄漏或缓存问题,但它似乎与应用程序中的积极内存分配和系统上的惰性内存释放更相关(如果操作系统有该策略,则不是有什么问题——如果是这样的话事实上它的工作方式)。也许我完全错过了一些东西。

有没有更好的方法来重复加载图像而不会出现这种占用和非主动缓解内存使用行为的情况?也许有一种方法可以强制降低应用程序的内存占用,或者有一种方法可以更智能地了解如何将图像加载到相同的对象或内存位置?我的目标是加载图像,处理它(获取缩略图,更改图像格式等),在内存中删除它,然后再做一次——所有这些都没有观察到内存增长。

--

跟进:

巴伐利亚,谢谢。包装 NSAutoreleasePool 确实解决了加载相同文件时的迭代内存增长:

但是,它并没有解决在图像被释放(并且 NSAutoreleasePool 耗尽)后内存保持增加的问题。例如,当加载我的 15MB JPEG 图像时,“Real Mem”内存从 8MB 稳定状态跳到大约 25MB,然后停留在那里。(我的应用程序只有一个 Interface Builder 按钮,该按钮具有一个连接 IBAction 的方法,该方法只调用我复制的 for 循环)。我希望在 for 循环完成后(或者如果只有一个图像被加载和释放),“Real Mem”统计数据将减少回名义应用程序级别的内存使用量。

调用 NSImage 功能时也可以加载后台的其他内容似乎是合理的,这可以增加内存。但是,不同大小的图像(15MB、30MB、50MB 等)会按比例增加应用程序的内存,这让我相信它不仅仅是这样的分配。

此外,如果我尝试连续加载单独的图像(例如,15MBjpeg-1.jpg、15MBjpeg-2.jpg 等),内存有时会为每个加载的新图像复合。例如,如果连续加载两个图像,则加载/释放后应用程序的“Real Mem”内存使用量现在大约为 50MB,并且根据我的观察,它永远不会减少。加载后续图像时,此行为会继续存在,因此应用程序在加载多个大图像后可能会占用数百 MB 的“Real Mem”内存。

有趣的是,如果我一遍又一遍地重新加载相同的图像,稳态内存不会增加。这是否表明正在进行某种缓存?同样,我的目标是在不增加内存的情况下对几个不同的图像文件进行批处理。提前致谢。

哦,我正在研究 Heapshot Analysis 文章 ATM,但至少想发布我的进度并查看是否有其他输入。

--

跟进#2

bbum,感谢您的精彩文章。我用我的测试程序运行 Instruments Allocations 并没有发现任何堆增长。在引用的博客文章中,我的方法是,1)单击我的 Interface Builder 界面上的“加载和释放图像”按钮(它调用加载/释放行为),2)每隔几秒钟单击几次“标记堆”在仪器分配中,然后 3) 重复 1) 和 2)。

使用这种方法,随着时间的推移,Heapshots 在 Heap Growth 列中始终报告 0 字节(每 5 秒单击 3 次,持续 15 秒),这意味着没有从基线 Heapshot 分配额外的内存。另外,在Statistics面板中,每次点击“Load and Release Image”按钮都会有一个13.25MB的Malloc,但是Live Bytes是0 Bytes,这意味着它已经被完全释放了。如果我三次单击“加载和释放图像”按钮,图像的总字节数报告为 39.75MB (3 * 13.25MB),这意味着 39.75MB 已分配,但由于实时字节数为 0 已完全释放。分配图快速上升并立即回落,因为这是一个非常快速的操作。内存的稳态使用没有泄漏,也没有增长,这一切似乎都是有道理的。

但是,现在我的“Real Mem”统计数据仍然很高怎么办?我知道活动监视器不是调试内存问题的标准。但是,直到我关闭程序,“Real Mem”仍然保持高位,然后“Real Mem”全部回到“免费”类别,这对我来说很奇怪。

我用两个图像(15MBjpeg-1.jpg、15MBjpeg-2.jpg)测试了同样的方法,只是用同样的方法复制代码,我再次观察到没有堆增长。显然,更多的分配被分配和释放。然而,现在“Real Mem”的增幅大约是仅加载和释放一张图像时的两倍。同样,它不会在测试程序的稳定状态下减少。

还有什么我可以做的吗?以下是单个图像加载/释放的测试代码,任何人都想尝试一下(只需将 IB 按钮连接到 openFiles):

谢谢阅读。:)

--

跟进#3

bbum,不,我没有启用垃圾收集(GC 在项目设置中设置为不支持)。我使用 vmmap 和 Instruments Allocations 中的 VM Tracker 栏调查了内存。当您说 VM Instruments 时,我假设您指的是 VM Tracker 数据,因为它报告的信息与 vmmap 相同。使用我的“加载和释放图像”按钮打开单个图像后,一些重要的内存数量包括以下内容(来自 VM Tracker):

Type         %ofRes  ResSize  VirtSize Res%  %AllDirty  DirtySize
__TEXT       38%     33.84MB  80.45MB  42%   0%         0Bytes
*Dirty*     32%     28.23MB  114.99MB 24%   100%       17.11MB
MALLOC_LARGE 14%     13.25MB  13.25MB  100%  0%         4KB
Carbon       11%     9.86MB   9.86MB   100%  20%        3.46MB
VM_ALLOCATE  9%      8.43MB   48.17MB  18%   49%        8.43MB
...

有趣的是,单个图像的后续加载/释放将Dirty和 VM_ALLOCATE 类型的“驻留大小”增加了 ~.3MB,并且这些类型的“Dirty Size”也随着时间的推移而增加。(VM_ALLOCATE 似乎是Dirty的一个子集)。随后的加载/发布似乎没有其他类型发生变化。

我不确定究竟要从这些数据中拿走什么,或者我如何使用它来让程序释放内存。看起来 VM_ALLOCATE 类型可能是没有被释放的块,但这只是推测。底层 NSImage 初始化实现的某些部分是否有可能保存图像文件的缓存并且不会释放它?同样,如前所述,与第一次加载/释放相比,同一图像文件的每次后续加载/释放几乎不消耗资源(CPU、磁盘研磨等)和挂钟时间,这让我很感兴趣。提前致谢。

0 投票
2 回答
271 浏览

cocoa - 在 NSTableView 中显示时图像模糊

我想在 NSTableView 中显示图像,但看起来很模糊。

在此处输入图像描述

在另一个窗口中,我使用 NSButton 显示它,然后就可以了,

在此处输入图像描述

我试图缩放图像以适应 NSTableView,但它仍然模糊,有人知道为什么吗?

[编辑] 我找到了解决方法:给 NSImageCell 添加边框,默认边框是无。我不知道为什么。

0 投票
1 回答
356 浏览

cocoa - 在 NSView 中隐藏子控件

我有一个带有多个子控件的 NSView。我知道我可以调用 [childControl setHidden:TRUE] 但我想知道是否可以阻止子控件的消息“drawRect:”。

我注意到不在 NSView 上调用 [super drawRect:NSZeroRect] 不会影响子控件。所以我的问题是谁调用子控件drawRect消息?如果有办法阻止它。

谢谢,何塞。

0 投票
2 回答
677 浏览

python - 从python中的NSImage中提取位图数据

我正在使用来自 NSImage 的数据构建 wx.MemoryDC,但生成的代码非常缓慢。在我看来,TIFFRepresentation -> ImageFromStream步骤是减慢速度的步骤。有什么办法可以避免这一步(所有这些流式传输),并直接从 NSImage 数据初始化 MemoryDC 吗?这是示例代码:

0 投票
1 回答
776 浏览

cocoa - NSScrollView 内的图像绘制在其他视图之上

我有一个自定义 NSView,NSScrollView它位于NSSplitView. 自定义视图使用以下绘图代码:

我已经尝试了每一种不同的类型,operation但图像仍然绘制在另一半的顶部,NSSplitView所以:

在此处输入图像描述

…而不是在NSScrollView. 我认为这与绘制所有内容而不是dirtyRect唯一有关,但我不知道如何编辑图像绘制代码以仅绘制位于dirtyRect. 我怎样才能防止它在顶部绘制,或者只为这个 NSImage 绘制脏矩形?

0 投票
3 回答
2481 浏览

cocoa - 可可 - 两个 NSImage 之间的淡入淡出?

我有一个 NSImage 显示一些信息的菜单,当它更新时,我希望新的(更新的)图像淡入。我知道这在 iPhone 上很容易,但在 OS X 中这可能吗?

0 投票
0 回答
185 浏览

cocoa - 可可使用纹理图集

我正在使用 NSView 子视图的 drawRect 将纹理图集加载到我的应用程序中:

这工作正常,但显示整个纹理图集。如何在图像的特定部分进行分区?图像为 1800x1200 像素,每张图像为 180x250 像素,因此图像一为 x=0, y=0, w=180, h=250,二为 x=180, y=0, w=180, h=250 , 等等。

我尝试更改上面的 x、y、w、h,但我的输出只是一个黑色图像。任何帮助,将不胜感激。

编辑:解决了,虽然我不确定这是否正确:

我将文件更改为 1100x1100 (这对解决方案没有影响,但会反映在答案中,所以我想注意它。然后我只是针对图像的错误区域(x,y)并将错误的大小传递给目标。新代码如下所示:

如果有不同的方式来实现这一点,我很乐意看到它。谢谢。