Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 调整glReadPixels返回的图像大小_C++_Opengl - Fatal编程技术网

C++ 调整glReadPixels返回的图像大小

C++ 调整glReadPixels返回的图像大小,c++,opengl,C++,Opengl,我使用glReadPixels将像素读入数组。但是这个图像的大小有点大,所以我想把它调整到一个特定的大小。我找不到OpenGL函数来调整图像大小。这种函数是否存在,或者我必须编写自己的函数来调整图像大小 注意:操作系统是Ubuntu 14.04 这是读取图像的代码 int img_w = 640; // screen size int img_h = 480; uint8_t img[img_w*img_h*3]; glReadPixels(0, 0, img_w, img_h, GL_RGB,

我使用
glReadPixels
将像素读入数组。但是这个图像的大小有点大,所以我想把它调整到一个特定的大小。我找不到OpenGL函数来调整图像大小。这种函数是否存在,或者我必须编写自己的函数来调整图像大小

注意:操作系统是Ubuntu 14.04

这是读取图像的代码

int img_w = 640; // screen size
int img_h = 480;
uint8_t img[img_w*img_h*3];
glReadPixels(0, 0, img_w, img_h, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);

// NEW image size
int new_w = 140;
int new_h = 140;
uint8_t new_img[new_w*new_h*3];
// Is there some opengl function to resize the image in `img` like:
gl_some_resize_func(img, new_w, new_h, new_img);

不,没有。它可能是某个图像处理库或您自己的功能,例如freeimage、openjpeg。OpenGL执行要显示的几何图形的输出,而不是光栅图像的操作

可以将图像渲染为纹理,使用缩放和过滤对其进行重采样,然后再次以极低的质量读取,但这不是建议的做法,因为与专用库相比,您总是会有质量损失。在移动平台上,在这种情况下,这也是一个组件损失,因为那里的纹理目前支持16位格式。唯一可以这样做的情况是当您卸载CPU或需要渲染纹理时,这实际上是以不同的方式完成的


同样,FreeImage、OpenJpeg、SDL或Qt为这项任务提供了更好的方法。

我的意思是,您可能听说使用
glReadPixels
是OpenGL中最慢的操作之一,如果可能的话,您应该避免从GPU同步传输内存。至于调整大小,如果您将图像渲染到具有全屏四元组的较小帧缓冲区,然后下载较小数量的像素,则速度可能会更快。@PeterT我真的不知道
glReadPixles
的替代方法。只需学习opengl两天。。。为了调整大小,您的意思是我可以创建一个新的更小的帧缓冲区,并将上面的原始
img
直接放入该帧缓冲区(opengl将自动“调整大小”),然后使用慢速
glReadPixels
读取帧缓冲区?如果该教程教您使用
glReadPixels
(或
glBegin/glEnd
,等等)你应该抛弃这个,为OpenGL3+找一个现代的。您正在使用的旧功能已被弃用多年,由于您刚刚开始学习OpenGL,最好开始学习正确的方法。@ybungalobill:
glReadPixels
不是过时的、旧的或“弃用的”。这是一个完全有效的API;事实上,这是从CPU上的默认帧缓冲区读取的唯一方法。@Nicol Bolas它是有效的,但它在连接到当前OpenGL上下文的窗口之外的行为实际上是标准未定义的。它可能起作用,也可能不起作用。但所有窗口系统都有其他方法,比创建OpenGL上下文更简单。哦,它不是帧缓冲区,而是输出,像素缓冲区。OpenGL是一个光栅化API,它至少有一半的功能是处理光栅图像,也称为纹理、图像和帧缓冲区。调整图像大小归结为在较小的像素上循环,并对每个像素使用正确的过滤在正确的位置对较大的像素进行采样。这是OpenGL支持的东西,事实上它非常擅长。如果你想知道ybungalobill指的是什么:画一个有纹理的四边形。然而(这确实必须说)默认的缩小和放大过滤器是模糊指定的,因此实现在如何实现方面有很大的回旋余地,因此产生的质量可能会有很大差异。如果需要非常精确、可重复和高质量的过滤结果,则最好使用定义良好的方法坚持使用专用的图像处理库(可以是GPU加速的和/或与OpenGL集成的)。或者实现您自己的过滤器(使用OpenCL或计算着色器)。@datenWalf:不仅有执行过滤的
glBlitNamedFramebuffer
,而且您还可以使用
imageLoad/Stores
运行计算着色器,而无需设置帧缓冲区。此外,默认的缩小过滤器是
GL\u NEAREST\u MIPMAP\u LINEAR
,默认的放大率是
GL\u LINEAR
。它精确地指定了两者的计算方式,除了
glGenerateTextureMipmap
,您可以使用它,也可以不使用它。@ybungalobill:我所说的“模糊指定”是,OpenGL规范对选择用于过滤的texel的算法以及如何计算过滤插值变量定义了非常严格的约束。但它在混合操作的精度以及如何与抖动相互作用方面留下了一些余地。这些细节被故意保留,以便为实现者提供其特定系统架构所需的回旋空间。是的,还指定了默认的插值方法。@ybungalobill:但是,如果您比较,比如说,AMD和NVidia GPU的过滤结果,或者甚至是来自不同代的同一供应商的GPU的过滤结果,或者甚至是使用不同的驱动程序设置(质量与精度设置),差异可能非常明显。因此,如果希望获得可重复的结果,内置过滤方法不是最佳选择。