将bmp文件压缩为jpg文件
目录
bmp文件压缩为jpg文件接口设计
/*******************************************************************
* file name: bmp2jpg
* author : 17666589210@163.com
* date : 2024-05-14
* function : Retrieve images, shrink them, and open them on the LCD screen
* note : None
* version : 1.0
* CopyRight (c) 2024 17666589210@163.com Right Reseverd
*******************************************************************/
需要的相关头文件
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include "jpeglib.h"
结构体
#pragma pack(1) // 设置取消字节对齐
// 文件信息结构体
typedef struct tag_bitmap_file_header
{
unsigned short file_type; // 文件标识,为字母ASCII码“BM”
unsigned int file_size; // 位图文件大小,以字节为单位
unsigned short reserved1; // 位图文件保留字,必须为0
unsigned short reserved2; // 位图文件保留字,必须为0
unsigned int offset_bits; // 文件开始到位图数据开始之间的偏移量字节
} bmp_file_header;
// 位图信息结构体
typedef struct tag_bitmap_info_header
{
unsigned int bitmap_info_size; // 图像描述信息快的大小,常为28H
int bitmap_width; // 图像宽度
int bitmap_height; // 图像高度
unsigned short planes; // 图像的plane总数(恒为1)
unsigned short image_depth; // 记录颜色的位数取值1(双色),4,6,24,,3
unsigned int compression; // 数据压缩方式(0:不压缩;1:8位压缩;2:4位压缩
unsigned int image_size; // 图像区数据的大小,必须是4的倍数
int x_pels_permeter; // 水平每米有多少像素,在设备无关位图中,填写00H
int y_pels_permeter; // 垂直每米有多少像素,在设备无关位图中,填写00H
unsigned int color_used; // 此图像所有的颜色数,不用,固定为0
unsigned int color_important; // 重要颜色数,不用,固定为0
} bmp_info_header;
#pragma pack() // 设置为字节对齐
函数调用
/********************************************************************
*
* name : write_JPEG_file
* function : 实现bmp文件压缩为jpb文件
* argument :
* @filename :需要生成jpg的文件名
* @bmpname :需要压缩的bmp文件
* @quality :生成的jpg文件的质量度
* retval : 调用成功返回生成文件后的结果
* author : 17666589210@163.com
* date : 2024/05/14
* note : none
*
* *****************************************************************/
int write_JPEG_file(char *filename, int quality, char *bmpname)
{
// 1.打开bmp图片文件
FILE *bmp_fb = fopen(bmpname, "rb");
if (NULL == bmp_fb)
{
printf("open bmp file faild\n");
return -1;
}
// 2.读取BMP图片文件的图像信息,获取BMP的宽和高
bmp_file_header headerinfo; // BMP头文件结构体申请内存 14字节
bmp_info_header fileinfo; // BMP文件信息结构体
fread(&headerinfo, 1, 14, bmp_fb);
fread(&fileinfo, 1, 40, bmp_fb); // 读取BMP头文件信息
// printf("current bmp width = %d\ncurrent bmp height = %d\n", fileinfo.bitmap_width, fileinfo.bitmap_height); // 输出BMP图片宽度和高度信息
// 3.读取原BMP图片的颜色分量
int pxsize = fileinfo.bitmap_width * fileinfo.bitmap_height * fileinfo.image_depth / 8;
printf("pxsize = %d\n", pxsize);
char bmp_buf[pxsize]; // 申请图片像素大小的缓冲区
fread(bmp_buf, 1, pxsize, bmp_fb); // 读取BMP颜色分量数据
char newbmp_buf[pxsize]; // 申请一块新的BMP图片大小的缓冲区
int cnt = 0;
for (int y = 480 - 1; y > 0; y--)
{
for (int x = 0; x < 800; x++)
{
for (int k = 2; k >= 0; k--)
{
newbmp_buf[cnt] = bmp_buf[(y * 800 + x) * 3 + k]; // 获取三个字节为一组的数据,并隔一行一列获取数据
cnt++;
}
}
}
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *outfile; /* target file */
unsigned char *row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
/* Step 1: allocate and initialize JPEG compression object */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo); // 初始化JPEG压缩对象
if ((outfile = fopen(filename, "wb")) == NULL)
{
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
/* Step 3: set parameters for compression */
cinfo.image_width = fileinfo.bitmap_width; /* image width and height, in pixels */
cinfo.image_height = fileinfo.bitmap_height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
/* Step 4: Start compressor */
jpeg_start_compress(&cinfo, TRUE);
/* Step 5: while (scan lines remain to be written) */
row_stride = fileinfo.bitmap_width * 3; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = &newbmp_buf[cinfo.next_scanline * row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
/* Step 6: Finish compression */
jpeg_finish_compress(&cinfo);
/* After finish_compress, we can close the output file. */
fclose(outfile);
/* Step 7: release JPEG compression object */
jpeg_destroy_compress(&cinfo);
return 1;
}
主函数
int main()
{
int quality = 100;
write_JPEG_file("demo.jpg", quality, "demo.bmp");
return 0;
}