在C语言编程中,处理静态图片是一个有趣且富有挑战性的任务。通过C语言,我们可以加载、处理并显示静态图片,这对于嵌入式系统、游戏开发以及图像处理应用来说都是非常有用的技能。本文将详细介绍在C语言中实现图...
在C语言编程中,处理静态图片是一个有趣且富有挑战性的任务。通过C语言,我们可以加载、处理并显示静态图片,这对于嵌入式系统、游戏开发以及图像处理应用来说都是非常有用的技能。本文将详细介绍在C语言中实现图片加载与显示的技巧。
在C语言中,常见的静态图片格式包括BMP、JPEG和PNG等。为了加载和显示这些图片,我们需要了解它们的格式并实现相应的解码算法。
BMP是一种位图格式,它直接存储了像素数据。在C语言中,我们可以通过读取BMP文件的像素数据来加载图片。
#include
#include
typedef struct { unsigned int width; unsigned int height; unsigned char *data;
} BMPImage;
BMPImage* loadBMP(const char *filename) { FILE *file = fopen(filename, "rb"); if (!file) { return NULL; } BMPImage *bmp = (BMPImage *)malloc(sizeof(BMPImage)); if (!bmp) { fclose(file); return NULL; } // 读取BMP文件头部信息 fread(&bmp->width, sizeof(unsigned int), 1, file); fread(&bmp->height, sizeof(unsigned int), 1, file); bmp->data = (unsigned char *)malloc(bmp->width * bmp->height * 3); // 读取像素数据 fread(bmp->data, sizeof(unsigned char), bmp->width * bmp->height * 3, file); fclose(file); return bmp;
}
void freeBMP(BMPImage *bmp) { if (bmp) { free(bmp->data); free(bmp); }
} JPEG格式是一种有损压缩的位图格式,解码JPEG图片需要使用专门的库,如libjpeg。
#include
#include
typedef struct { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; jmp_buf setjmp_buffer;
} my_error_mgr;
typedef my_error_mgr * my_error_ptr;
void my_error_exit(j_common_ptr cinfo) { my_error_ptr myerr = (my_error_ptr) cinfo->err; (*cinfo->err->output_message) (cinfo); longjmp(myerr->setjmp_buffer, 1);
}
void loadJPEG(const char *filename, unsigned char **data, int *width, int *height) { FILE *file = fopen(filename, "rb"); struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; if (!file) { return; } cinfo.err = jpeg_std_error(&jerr); jerr.error_exit = my_error_exit; if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&cinfo); fclose(file); return; } jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, file); jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); *width = cinfo.image_width; *height = cinfo.image_height; *data = (unsigned char *)malloc(*width * *height * 3); while (jpeg_read_scanlines(&cinfo, (JSAMPROW)(*data), 1)) { // 处理每一行 } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); fclose(file);
} PNG格式是一种无损压缩的位图格式,解码PNG图片需要使用专门的库,如libpng。
#include
void loadPNG(const char *filename, unsigned char **data, int *width, int *height) { FILE *file = fopen(filename, "rb"); png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_infop info_ptr = png_create_info_struct(png); png_infop end_info = png_create_info_struct(png); png_bytep row; int rowbytes; if (!file || !png || !info_ptr || !end_info) { return; } png_init_io(png, file); png_set_error_fn(png, NULL, NULL, NULL); png_read_info(png, info_ptr); png_set_strip_16(png); png_set_expand(png); png_set_interlace_handling(png); png_read_update_info(png, info_ptr); *width = png_get_image_width(png, info_ptr); *height = png_get_image_height(png, info_ptr); rowbytes = png_get_rowbytes(png, info_ptr); *data = (unsigned char *)malloc(*width * *height * 3); row = (png_bytep)malloc(rowbytes); png_read_image(png, row); for (int y = 0; y < *height; ++y) { memcpy(*data + y * rowbytes, row, rowbytes); } png_read_end(png, NULL); png_destroy_read_struct(&png, &info_ptr, &end_info); fclose(file); free(row);
} 在C语言中,显示图片需要根据不同的显示环境选择不同的方法。以下是一些常用的显示方法。
SDL(Simple DirectMedia Layer)是一个跨平台的开源开发库,可以用于开发2D和3D游戏以及多媒体应用程序。
#include
void displayImage(SDL_Renderer *renderer, unsigned char *data, int width, int height) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 24, SDL_PIXELFORMAT_RGB24, 0, 0, 0, 0); if (!surface) { return; } SDL_LockSurface(surface); memcpy(surface->pixels, data, width * height * 3); SDL_UnlockSurface(surface); SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface); if (texture) { SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); SDL_DestroyTexture(texture); } SDL_FreeSurface(surface);
} OpenGL是一个跨平台的应用程序编程接口(API),用于渲染2D和3D矢量图形。
#include
#include
void displayImage(GLFWwindow *window, unsigned char *data, int width, int height) { int windowWidth = 800; int windowHeight = 600; glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow *glFWwindow = glfwCreateWindow(windowWidth, windowHeight, "Image Display", NULL, NULL); if (!glFWwindow) { glfwTerminate(); return; } glfwMakeContextCurrent(glFWwindow); glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { return; } GLuint textureID; glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); while (!glfwWindowShouldClose(glFWwindow)) { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, 1.0f); glEnd(); glfwSwapBuffers(glFWwindow); glfwPollEvents(); } glDeleteTextures(1, &textureID); glfwDestroyWindow(glFWwindow); glfwTerminate();
} 在C语言中处理静态图片需要了解图片格式、解码算法和显示方法。通过使用BMP、JPEG、PNG等格式的解码函数和SDL、OpenGL等库,我们可以轻松地在C语言中加载和显示静态图片。希望本文能够帮助你掌握C语言中的静态图片处理技巧。