如何在 OpenGL 中截取屏幕截图
如何使用 C++ 截取 OpenGL 窗口的屏幕截图并将其保存到文件。
我找到了 glReadPixels()
函数, 但我不知道下一步该做什么。例如,我可以在哪里设置文件的路径?
如果不难的话,请写代码。
How to take a screenshot of an OpenGL window in C++ and save it to file.
I found the glReadPixels()
function,
but I don't know what to do next. Where I can set path to a file, for example?
If not difficult, write code, please.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
这段代码捕获 OpenGL 窗口并导出到 BMP 文件。您必须有 FreeImage 库才能运行它。
This piece of code captures the OpenGL window and export to a BMP file. You must have FreeImage library to run it.
glReadPixels 将复制位写入您提供的内存缓冲区中。您必须手动格式化数据(为您选择的图像格式)并将其写入磁盘glReadPixels 返回。
glReadPixels will copy the bits into a memory buffer that you supply. You have to manually format the data (to the image format of your choice) and write it to disk after glReadPixels returns.
可运行示例
每次在窗口上单击鼠标时,都会使用当前屏幕截图创建一个
tmpX.ppm
文件。您可以在 Linux 上使用
eog
查看此文件,并使用文本编辑器检查它。要在不显示窗口的情况下进行渲染,请参阅:如何使用GLUT/OpenGL 渲染到文件?
编译:
在 Ubuntu 15.10、OpenGL 4.5.0 NVIDIA 352.63 上测试。
Vulkan
这个例子刚刚工作:https ://github.com/SaschaWillems/Vulkan/blob/b9f0ac91d2adccc3055a904d3a8f6553b10ff6cd/examples/screenshot/screenshot.cpp 如何运行它:是否可以在 Vulkan 中不使用 Surface 进行离屏渲染?
Runnable example
Each time you click with the mouse on the window, a
tmpX.ppm
file is created with the current screenshot.You can view this file for example with
eog
on Linux, and inspect it with a text editor.To render without showing a window, see: How to use GLUT/OpenGL to render to a file?
Compile with:
Tested on Ubuntu 15.10, OpenGL 4.5.0 NVIDIA 352.63.
Vulkan
This example just worked: https://github.com/SaschaWillems/Vulkan/blob/b9f0ac91d2adccc3055a904d3a8f6553b10ff6cd/examples/screenshot/screenshot.cpp how to run it: Is it possible to do offscreen rendering without Surface in Vulkan?
一个简单快速的解决方案。
tga
文件扩展名。下面是代码:
并调用函数:
将 TARGA 文件转换为 PNG 的 bash 脚本:
A simple and quick solution.
tga
file extension.Here is the code:
And calling the function:
A bash script to convert TARGA files to PNG:
将该数据保存到文件中要么必须自己完成,要么使用第三方库 - OpenGL 没有这样的功能。
如果您想自己动手,Windows .bmp 可能是最简单的 - 维基百科有一个关于文件格式。否则,您可以使用图像保存/加载库:libpng、libjpeg 等进行低级控制,或 devIL (还有其他库,但这是我最喜欢的,它是一个非常通用的库,与 GL 配合良好)用于高级“Just do it”图像 I/O。
Saving that data to a file is something you'll either have to do yourself or use a third-party library for - OpenGL has no such feature.
Windows .bmp is probably the easiest if you're looking to do it yourself - Wikipedia has a pretty good explanation of the file format. Otherwise you can use image saving/loading libraries: libpng, libjpeg, etc. for low-level control, or devIL (there are others, but this is my favorite, and it's an extremely versatile library that goes well with GL) for high-level "just do it" image i/o.
您可以使用@Rafael的答案和OpenCV保存屏幕截图:
感谢OpenCV:https://stackoverflow.com/a/9098883/10152334
You can save screenshot with @Rafael's answer and OpenCV:
Thanks for OpenCV: https://stackoverflow.com/a/9098883/10152334
一般来说,OpenGL不提供保存图像的函数。我认为最快、最简单的方法是保存为 .PPM 格式。然而,这种格式是未压缩的,这意味着它的文件大小会非常大。目前只有相当多的程序可以支持它。
我更喜欢将图像保存为 .png 文件,该文件经过压缩但也提供无损图像并受到许多浏览器的支持。要将 OpenGL 保存为 .png 格式,我首先推荐 PNGwriter。它非常简单且易于使用。例如,要在位置 (x, y) 保存颜色为 (R, G, B) 的图像像素,您的代码将为(请参阅 PNGwriter 网站中的“快速入门”):
请注意,由于 PNGwriter 保存每个像素从图像的左上角开始,而从 glReadPixels() 获取的数组从窗口的左下角开始,保存整个图像的代码可能如下所示:
Generally, OpenGL don't provide functions to save image. I think the fastest and simplest way to do this is save to .PPM format. However, this kind of format is uncompressed which means it's file size would be very large. And it can be support only by quite a few programs nowadays.
I prefer to save image to .png file which is compressed but also gives lossless image and supported by many browsers. To save the OpenGL to .png format, I first recommend the PNGwriter. It's pretty simple and easy to use. For example, to save a pixel of a image with color (R, G, B) in the position (x, y), your code will be(see "quickstart" in the PNGwriter website):
Note that, since the PNGwriter save each pixel starting from the top-left corner of the image, while the array get from glReadPixels() start from the bottom-left of the window, your code to save the whole image might probably look like this:
我修改了 Ciro Santilli OurBigBook.com 的答案,以包括线程和更好的性能。
I have modified Ciro Santilli OurBigBook.com 's answer to include threading and better performance.