通过OpenGL实现图像缩放(KeepAspectRatioByExpanding) 转载文章
我正在尝试仅使用OpenGL glVertex2f()
.和OpenGL在中实现图像缩放
让我解释一下:加载QImage
并使用glTexImage2D()
将其发送到图形处理器后,我必须根据Qt的规范执行图像缩放操作。Qt定义了这3个操作(见下图):
![](https://ask.qcloudimg.com/http-save/yehe-900000/7f17e4d1ee7834294fcd314362a5ee35.png?imageView2/2/w/1620)
我认为这是唯一的方法,因为我的应用程序是一个Qt插件,这个任务需要在类的paint()
方法中完成。IgnoreAspectRatio
操作非常简单,现在就能正常工作。KeepAspectRatio
最初给我带来了一些麻烦,但现在它也可以工作了。不幸的是,KeepAspectRatioByExpanding
让我头疼。
我正在分享我到目前为止所做的事情,我感谢你在这个问题上的帮助:
main.cpp:
#include "oglWindow.h"
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
oglWindow w;
w.show();
return a.exec();
}
oglWindow.cpp:
#include "oglWindow.h"
#include "glwidget.h"
#include <QGridLayout>
oglWindow::oglWindow(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
GLWidget *openGL = new GLWidget(this);
QGridLayout *layout = new QGridLayout;
setLayout(layout);
}
oglWindow::~oglWindow()
{
}
oglWindow.h:
#ifndef oglWindow_H
#define oglWindow_H
#include <QtGui/QMainWindow>
#include "ui_yuv_to_rgb.h"
class oglWindow : public QMainWindow
{
Q_OBJECT
public:
oglWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
~oglWindow();
private:
Ui::oglWindowClass ui;
};
#endif // oglWindow_H
glwidget.cpp:
#ifdef _MSC_VER
#include <windows.h>
#include <GL/glew.h>
#include <GL/gl.h>
#else
#include <GL/gl.h>
#endif
#include "glwidget.h"
#include <QDebug>
#include <iostream>
#include <fstream>
#include <assert.h>
static const char *p_s_fragment_shader =
"#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect tex;"
"uniform float ImgHeight, chromaHeight_Half, chromaWidth;"
"void main()"
"{"
" vec2 t = gl_TexCoord[0].xy;" // get texcoord from fixed-function pipeline
" float CbY = ImgHeight + floor(t.y / 4.0);"
" float CrY = ImgHeight + chromaHeight_Half + floor(t.y / 4.0);"
" float CbCrX = floor(t.x / 2.0) + chromaWidth * floor(mod(t.y, 2.0));"
" float Cb = texture2DRect(tex, vec2(CbCrX, CbY)).x - .5;"
" float Cr = texture2DRect(tex, vec2(CbCrX, CrY)).x - .5;"
" float y = texture2DRect(tex, t).x;" // redundant texture read optimized away by texture cache
" float r = y + 1.28033 * Cr;"
" float g = y - .21482 * Cb - .38059 * Cr;"
" float b = y + 2.12798 * Cb;"
" gl_FragColor = vec4(r, g, b, 1.0);"
"}";
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent), _frame(NULL)
{
setAutoFillBackground(false);
setMinimumSize(640, 480);
/* Load 1280x768 YV12 frame from the disk */
_frame = new QImage(1280, 768, QImage::Format_RGB888);
if (!_frame)
{
qDebug() << "> GLWidget::GLWidget !!! Failed to create _frame";
return;
}
std::ifstream yuv_file("bloco.yv12", std::ios::in | std::ios::binary | std::ios::ate);
if (!yuv_file.is_open())
{
qDebug() << "> GLWidget::GLWidget !!! Failed to load yuv file";
return;
}
int yuv_file_sz = yuv_file.tellg();
unsigned char* memblock = new unsigned char[yuv_file_sz];
if (!memblock)
{
qDebug() << "> GLWidget::GLWidget !!! Failed to allocate memblock";
return;
}
yuv_file.seekg(0, std::ios::beg);
yuv_file.read((char*)memblock, yuv_file_sz);
yuv_file.close();
qMemCopy(_frame->scanLine(0), memblock, yuv_file_sz);
delete[] memblock;
}
GLWidget::~GLWidget()
{