从不可见的 AWT 组件创建图像?
我正在尝试创建不可见 AWT 组件的图像(屏幕截图)。我无法使用 Robot
类的屏幕捕获功能,因为该组件在屏幕上不可见。尝试使用以下代码:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
component.paintAll(g);
有时可以工作,但如果组件包含诸如文本框或按钮之类的东西,或者某种 OpenGL / 3D 组件(这些东西被排除在图像之外!),则不起作用。我怎样才能正确截取整个事件的屏幕截图?
I'm trying to create an image (screen-shot) of a non-visible AWT component. I can't use the Robot
classes' screen capture functionality because the component is not visible on the screen. Trying to use the following code:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
component.paintAll(g);
Works sometimes, but does not work if the component contains things such as a text box or button, or some sort of OpenGL / 3D component (these things are left out of the image!). How can I take a proper screenshot of the whole thing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
(免责声明:woops..这似乎不适用于 AWT )-:
我不敢相信没有人建议
SwingUtilities.paintComponent
或CellRendererPane.paintComponent
正是为此目的而制作的。从前者的文档来看:下面是一个示例方法,它将不可见组件绘制到图像上:
这是一个测试上述类的代码片段:
这是生成的图像:
(disclamer: woops.. this doesn't seem to work for AWT )-:
I can't believe no one has suggested
SwingUtilities.paintComponent
orCellRendererPane.paintComponent
which are made for this very purpose. From the documentation of the former:Here is an example method that paints a non-visible component onto an image:
Here is a snippet of code that tests the above class:
And here is the resulting image:
Component
有一个方法paintAll(Graphics)
(正如您已经发现的那样)。该方法将在传递的图形上绘制自身。但在调用paint方法之前,我们必须预配置图形。这就是我在 java.sun.com< 中发现的有关 AWT 组件渲染的信息/a>:因此,这就是我们的结果方法:
这也是代替使用
Robot
来处理可见组件的更好方法。编辑:
很久以前,我使用了上面发布的代码,并且它有效,但现在不行了。所以我进一步寻找。我有一个经过测试的工作方式。它很脏,但是有用。它的想法是制作一个 JDialog,将其放在屏幕边界之外的某个位置,将其设置为可见,然后将其绘制在图形上。
代码如下:
因此,这也适用于 Windows 和 Mac。另一个答案是在虚拟屏幕上绘制它。但这不需要它。
Component
has a methodpaintAll(Graphics)
(as you already have found). That method will paint itself on the passed graphics. But we have to pre-configure the graphics before we call the paint method. That's what I found about the AWT Component rendering at java.sun.com:So, this is our resulting method:
This is also the better way instead of using
Robot
for the visible components.EDIT:
A long time ago I used the code I posted here above, and it worked, but now not. So I searched further. I have a tested, working way. It is dirty, but works. The Idea of it is making a JDialog, put it somewhere out of the Screen bounds, set it visible, and then draw it on the graphics.
Here is the code:
So, this will work also on Windows and Mac. The other answer was to draw it on a virtual screen. But this doesn't need it.
很好的问题,我自己也时常思考这个问题!
正如您已经写过的,将 3D 和 AWT 等重量级组件渲染到图像上是一个大问题。这些组件(几乎)直接传输到图形卡,因此它们无法使用正常的
paintComponent
内容重新渲染为图像,您需要操作系统的帮助或自己渲染这些组件。1. 制作自己的图像渲染器
对于每个没有图像渲染方法的组件,您需要创建自己的图像渲染器。例如,使用 jogl 您可以使用此 方法 (SO 帖子)。
2. 渲染到虚拟屏幕上
先决条件:
然后你可以使用 Xvfb 将整个程序渲染到虚拟屏幕上,然后从像这样的虚拟屏幕:
也许您需要通过传递要渲染的程序的大小来稍微调整 Xvfb (
-screen 0 1024x768x24
)。Excellent question, I've thought about this myself from time to time!
As you already have written, that rending heavy weight components such as 3D and AWT onto an image is a big problem. These components are (almost) directly transferred to the graphic card so they cannot be re-rendered to an image using the normal
paintComponent
stuff, you need help from the operative system or doing your own rendering of these components.1. Making your own to image renderer
For each component that does not have a to image rendering method you need to create your own. For example using jogl you can take a off-screen screenshot using this method (SO post).
2. Rendering onto a virtual screen
Prerequisites:
Then you can use Xvfb to render the whole program onto a virtual screen and then taking a screenshot from that virtual screen like this:
Maybe you need to tweek Xvfb a little bit by passing the size of the program you want to render to it (
-screen 0 1024x768x24
).Screen Image 类展示了如何为 Swing 组件完成此操作。我从未尝试过使用 AWT 组件,购买后我猜想概念是相同的。
The Screen Image class shows how this can be done for Swing components. I've never tried it with AWT components, buy I could guess the concept would be the same.
像这样的事情怎么样?包含所有组件的 JFrame 是不可见的。
}
<代码>
How about something like this. The JFrame that holds all of the components is not visible.
}