问题标签 [bufferedimage]

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 回答
12093 浏览

java - Java:如何快速复制 BufferedImage 的像素?(包括单元测试)

我想将 ARGB 值从源复制(矩形区域)BufferedImage到目标BufferedImage。不应该进行合成:如果我复制一个 ARGB 值为 0x8000BE50(alpha 值为 128)的像素,那么目标像素必须正好是0x8000BE50,完全覆盖目标像素。

我有一个非常精确的问题,我做了一个单元测试来显示我需要什么。单元测试功能齐全且独立,并且通过良好并且正在做我想要的。

但是,我想要一种更快、内存效率更高的方法来替换copySrcIntoDstAt (...)。

这就是我的问题的重点:我不是在追求如何以更快的方式“填充”图像(我所做的只是进行单元测试的一个例子)。我只想知道什么是一种快速且内存高效的方法(即快速且不创建不必要的对象)。

我所做的概念验证实现显然非常节省内存,但速度很慢(对每个像素做一个getRGB和一个)。setRGB

示意性地,我得到了这个:(其中 A 表示复制前目标图像中的相应像素)

我想要这个:

其中“B”表示来自src图像的像素。

请注意,我正在寻找完全替代copySrcIntoDstAt(...)方法,而不是 API 链接/报价。

0 投票
5 回答
3393 浏览

java - 删除图像后JFrame不刷新

我第一次在 JFrame 中处理图像,我遇到了一些问题。我成功地将图像放在我的 JFrame 上,现在我想在 2 秒后从 JFrame 中删除我的图像。但是 2 秒后,图像不会消失,除非我调整框架的大小或者我最小化然后最大化框架。如果可以的话,请帮助我。谢谢。

这是代码:

System.out.println("图片" + f.getAbsolutePath()); BufferedImage 图像 = ImageIO.read(f); MyBufferedImage img = new MyBufferedImage(image); img.resize(400, 300); img.setSize(400, 300); img.setLocation(50, 50); getContentPane().add(img);

this.setSize(600, 400); this.setLocationRelativeTo(null); this.setVisible(true);

线程.sleep(2000); System.out.println("2 秒结束");

getContentPane().remove(img);

这是 MyBufferedImage 类:

}

0 投票
4 回答
1932 浏览

java - 在单独的线程中更新 BufferedImage 的单独区域是否安全?

我有一组BufferedImage实例,一个主图像和一些通过调用getSubImage主图像创建的子图像。子图像不重叠。我也在对子图像进行修改,我想将其拆分为多个线程,每个子图像一个。

根据我对如何和工作的理解BufferedImage,这应该是安全的,因为:RasterDataBuffer

  • BufferedImage(及其各自的WritableRasterand )的每个实例SampleModel只能从一个线程访问。
  • 共享ColorModel是不可变的
  • 没有可以修改的DataBuffer字段(唯一可以更改的是支持数组的元素。)
  • 在单独的线程中修改数组的不相交段是安全的。

但是,我在文档中找不到任何说明这样做绝对安全的内容。我可以假设它是安全的吗?我知道可以处理 childRaster的副本,但由于内存限制,我更愿意避免这种情况。

否则,是否可以在不复制父图像区域的情况下使操作线程安全?

0 投票
2 回答
7685 浏览

java - BufferedImage.getGraphics() 导致内存泄漏,有解决办法吗?

我在调用 BufferedImage.getGraphics() 方法时遇到一些框架 API 的问题,从而导致内存泄漏。这个方法的作用是它总是调用 BufferedImage.createGraphics()。在 Windows 机器上, createGraphics() 由 Win32GraphicsEnvironment 处理,Win32GraphicsEnvironment在其字段displayChanger中保留一个侦听器列表。当我在 BufferedImage someChart上调用 getGraphics 时,someChart的 SurfaceManager(它保留对someChart的引用)被添加到 Win32GraphicsEnvironment 中的侦听器映射中,从而防止someChart被垃圾收集。之后什么都不会删除someChart的 SurfaceManager听众地图。

通常,一旦调用 getGraphics,阻止 BufferedImage 被垃圾收集的总结路径如下:

GC Root -> localGraphicsEnvironment(Win32GraphicsEnvironment) -> displayChanger(SunDisplayChanger) -> listeners(Map) -> key (D3DChachingSurfaceManager) -> bImg(BufferedImage)

我本可以更改框架的代码,以便在每次调用 BufferedImage.getGraphics() 之后,我都会保留对 BufferedImage 的 SurfaceManager 的引用。然后,我获取 localGraphicsEnvironment,将其转换为 Win32GraphicsEnvironment,然后使用对 BufferedImage 的 SurfaceManager 的引用调用 removeDisplayChangedListener()。但我认为这不是解决问题的正确方法。

有人可以帮我解决这个问题吗?非常感谢!


更多细节和发现

我试图添加到我的 UI 的组件是在每次重绘时调用 BufferedImage.getGraphics() 。因此,displayChanger(在SunGraphicsEnvironment内部)保留的垃圾数量应该随着组件的重新绘制而增加。

然而,事情的行为很奇怪:

当我在我的 UI 上计算肯定会触发重绘的操作时,然后根据我的计数检查displayChanger内的垃圾侦听器的数量,它们不匹配。(例如,我点击之前有8个听众,我点击了60次。毕竟只有18个听众。)

另一方面,如果我打开断点,并进入向displayListeners添加内容的过程,每次单击都会在displayListeners中产生一个新条目。因此,displayListeners持有的每个 BufferedImage 都变成了垃圾。

我考虑过SurfaceManager,作为displayListeners的key,可以共享或者重用,但是我的实验排除了这种可能性。我还考虑过缓存,我故意通过使每次重绘调用都独一无二来防止缓存发生。尽管如此,我仍然不知道这是如何发生的以及如何解决泄漏。

0 投票
2 回答
15938 浏览

java - 如何使用 TYPE_BYTE_GRAY 使用 AWT 高效地创建灰度缓冲图像

我需要从 nio ShortBuffer 中的数据创建灰度图像。我有一个函数可以将 ShortBuffer 中的数据映射到无符号字节,但它位于 int 中(很容易更改)。我发现的方法使用 RGB 加透明颜色模型,并且似乎效率很低。我无法看到如何应用 TYPE_BYTE_GRAY 并修改代码。我是 Java 新手。这是我的代码:

蒂亚奈特

0 投票
1 回答
269 浏览

c# - 对于 c# 中的重型图形应用程序,哪个将是更有效的双缓冲或缓冲图形?

你好,我有一个繁重的图形应用程序,每次我必须在 2-10 秒内绘制图形,这取决于通过 UDP 向我的应用程序发送数据的源应用程序;

我有一些静态图形,它们没有变化,有些是半动态的,这意味着它们有时会更新并且通常保持不变,所有其他图形都是动态的,大约有 8000 个动态对象

我正在使用 c# 并学习标题中给出的两种技术,在这种情况下需要帮助的一种会更有效

提前感谢;

0 投票
2 回答
749 浏览

java - 在由瓷砖组成的 BufferedImage 中旋转特定瓷砖

我正在尝试旋转 BufferedImage 中的图块(bufferedimage 由图块组成),但我被卡住了,似乎找不到答案。我已经用谷歌搜索了几个小时,但找不到任何教程。所以我决定来这里寻求帮助。

我想旋转缓冲图像右下角的交叉(平铺)。我想将它旋转 90 度,而其他瓷砖不受影响。

我正在做一个机器人可视化,所以每当机器人到达铁路道口时,道口就会转 90 度,它会移动到另一条铁路。我添加了“旋转”按钮,以便能够单独测试旋转。单击按钮时,我希望将十字路口旋转 90 度。

这是代码。您可以复制并运行它。

不要忘记将图像复制到开发环境(Eclipse 等)的图像文件夹中。图像为 130 X 130。

在下面的“VisPanel”类中的图像名称是: 将图像保存为“railHorizo​​ntal.JPG”、“railVertical2.JPG”和“railCrossing2.JPG”。

这是图像。

替代文字 http://www.freeimagehosting.net/uploads/ed6f294d32.jpg

替代文字 http://www.freeimagehosting.net/uploads/dba1a7f996.jpg

替代文字 http://www.freeimagehosting.net/uploads/f9d114ac1e.jpg

编码:

谢谢你的帮助。

0 投票
2 回答
7201 浏览

java - Scala - 当一个参数必须为空时,如何显式选择要使用的重载方法?

全部,

我正在通过使用 BufferedImages 和 Raster 对象在 Scala 中进行一些图像处理。我正在尝试使用以下代码获取缓冲图像中的所有像素。

现在,当我读入相对较大的文件时,这工作正常。当我读入 20x20 PNG 文件时,我得到一个 ArrayIndexOutOfBoundsException:

我在网上读到,解决这个问题的方法是不预先分配像素缓冲区,而是传入一个空值并使用 Raster.getPixels 方法返回的值。

这是我的问题。当我采用天真的方法并将 Nil 作为最后一个参数传递时:

我得到错误

所以很明显编译器无法确定我试图调用的两种方法中的哪一种;这是模棱两可的。如果我使用的是 Java,我会强制转换为 null 以明确我的意图。我不太清楚如何在 Scala 中获得相同的效果。我尝试过的事情:

知道如何明确告诉编译器我想要将 Int 数组作为最后一个参数而不是 Float 数组的方法吗?

编辑:正如答案指出的那样,我将 Nil 与 null 混为一谈。Nil 是一个空列表。请参阅以下博客文章

另外,我应该指出,数组越界异常是我的错(因为这些事情经常发生)。问题是我假设光栅有 3 个通道,但我的图像有 4 个通道,因为我是这样创建的。我改为按如下方式预分配数组:

谢谢您的帮助

0 投票
2 回答
4231 浏览

java - 将 BufferedImage 绘制到另一个 BufferedImage 的最快方法

我正在尝试在 Java 中创建图像马赛克。我计算我正在创建的新图像的大小,然后对于将成为马赛克一部分的每个子图像,我进行一次绘制调用。

在伪代码中:

有一个更好的方法吗?我希望有某种直接复制操作可用,因为我不想将子图像转换或缩放成更大的图像。类似于每个子图像的光栅的arraycopy。我注意到有一个接受 Raster 对象的 setData 方法,但该方法指出 Raster 必须位于相同的坐标空间中。

有什么想法吗?这是我的程序中的一个瓶颈,我希望它尽可能快。

编辑:事实证明我错了(通常在没有硬数据的情况下做出假设)关于瓶颈在哪里。我有一个错误,即一遍又一遍地读取多张 3MB 图片,而不是使用缓存在内存中的缩小版本的图像。当我进行修复时,我的运行时间从 50 分钟变为 15 秒。

0 投票
1 回答
1365 浏览

java - 如何使用java识别空白/不可见图像

我想知道是否有可能识别出java 中的BufferedImage是空白(浏览器中的用户不可见)图像。