opengl es 如何将图片的RGB格式转换成unsigned char*并且保存成jpg完整例子
时间: 2024-05-01 10:22:12 浏览: 155
下面是一个完整的示例代码,它使用OpenGL ES将纹理转换为RGB格式的像素数据,并使用libjpeg-turbo库将像素数据保存为JPG格式的图像文件。
```
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <jpeglib.h>
#include <turbojpeg.h>
#include <stdio.h>
#include <stdlib.h>
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define TEXTURE_FILE "texture.jpg"
#define IMAGE_FILE "image.jpg"
static const char *vertexShaderSource =
"attribute vec4 a_position;\n"
"attribute vec2 a_texcoord;\n"
"varying vec2 v_texcoord;\n"
"void main() {\n"
" gl_Position = a_position;\n"
" v_texcoord = a_texcoord;\n"
"}\n";
static const char *fragmentShaderSource =
"precision mediump float;\n"
"uniform sampler2D u_texture;\n"
"varying vec2 v_texcoord;\n"
"void main() {\n"
" gl_FragColor = texture2D(u_texture, v_texcoord);\n"
"}\n";
static const GLfloat vertices[] = {
-1.0f, 1.0f, 0.0f, // top left
-1.0f, -1.0f, 0.0f, // bottom left
1.0f, -1.0f, 0.0f, // bottom right
1.0f, 1.0f, 0.0f, // top right
};
static const GLfloat texcoords[] = {
0.0f, 0.0f, // top left
0.0f, 1.0f, // bottom left
1.0f, 1.0f, // bottom right
1.0f, 0.0f, // top right
};
static const GLushort indices[] = {
0, 1, 2,
0, 2, 3,
};
int main(int argc, char *argv[])
{
// Initialize EGL display and context
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
EGLint major, minor;
eglInitialize(display, &major, &minor);
EGLint attributes[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
EGLConfig config;
EGLint num_configs;
eglChooseConfig(display, attributes, &config, 1, &num_configs);
EGLint context_attributes[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attributes);
// Create window surface
EGLSurface surface;
EGLint surface_attributes[] = {
EGL_WIDTH, WINDOW_WIDTH,
EGL_HEIGHT, WINDOW_HEIGHT,
EGL_NONE
};
surface = eglCreateWindowSurface(display, config, NULL, surface_attributes);
// Make the context current
eglMakeCurrent(display, surface, surface, context);
// Load texture from file
unsigned char *texture_data;
int texture_width, texture_height;
tjhandle tj = tjInitDecompress();
FILE *fp = fopen(TEXTURE_FILE, "rb");
fseek(fp, 0, SEEK_END);
long file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
texture_data = (unsigned char *)malloc(file_size);
fread(texture_data, 1, file_size, fp);
fclose(fp);
int tj_width, tj_height, tj_subsamp;
tjDecompressHeader2(tj, texture_data, file_size, &tj_width, &tj_height, &tj_subsamp);
texture_width = tj_width;
texture_height = tj_height;
unsigned char *texture_pixels = (unsigned char *)malloc(texture_width * texture_height * 3);
tjDecompress2(tj, texture_data, file_size, texture_pixels, texture_width, 0, texture_height, TJPF_RGB, TJFLAG_FASTDCT);
tjDestroy(tj);
// Create texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_pixels);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Create program
GLuint program;
GLint success;
char info_log[512];
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertexShaderSource, NULL);
glCompileShader(vertex_shader);
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
fprintf(stderr, "Failed to compile vertex shader: %s\n", info_log);
exit(1);
}
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
fprintf(stderr, "Failed to compile fragment shader: %s\n", info_log);
exit(1);
}
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(program, 512, NULL, info_log);
fprintf(stderr, "Failed to link program: %s\n", info_log);
exit(1);
}
glUseProgram(program);
// Set up vertex attributes
GLint position_attrib = glGetAttribLocation(program, "a_position");
glVertexAttribPointer(position_attrib, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(position_attrib);
GLint texcoord_attrib = glGetAttribLocation(program, "a_texcoord");
glVertexAttribPointer(texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
glEnableVertexAttribArray(texcoord_attrib);
// Set up texture uniform
GLint texture_uniform = glGetUniformLocation(program, "u_texture");
glUniform1i(texture_uniform, 0);
// Render to framebuffer
GLuint framebuffer, renderbuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenRenderbuffers(1, &renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, WINDOW_WIDTH, WINDOW_HEIGHT);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
// Read framebuffer pixels
unsigned char *pixels = (unsigned char *)malloc(WINDOW_WIDTH * WINDOW_HEIGHT * 3);
glReadPixels(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels);
// Save image to file
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
FILE *fp2 = fopen(IMAGE_FILE, "wb");
jpeg_stdio_dest(&cinfo, fp2);
cinfo.image_width = WINDOW_WIDTH;
cinfo.image_height = WINDOW_HEIGHT;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_start_compress(&cinfo, TRUE);
JSAMPROW row_pointer[1];
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = &pixels[(cinfo.image_height - cinfo.next_scanline - 1) * cinfo.image_width * 3];
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(fp2);
// Clean up
free(texture_data);
free(texture_pixels);
free(pixels);
glDeleteProgram(program);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
glDeleteTextures(1, &texture);
glDeleteFramebuffers(1, &framebuffer);
glDeleteRenderbuffers(1, &renderbuffer);
eglDestroySurface(display, surface);
eglDestroyContext(display, context);
eglTerminate(display);
return 0;
}
```
注意:此示例代码仅支持RGB格式的图像文件,如果要处理其他格式的图像文件,请根据需要进行适当修改。
阅读全文