jpg实现图像缩放

    jpg其实性质和bmp的差不多,但是jpg是经过压缩的,所以在读取jpg的图像数据时,不能像bmp图像那样直接read了,而是有专门的动态库函数支持,需要利用。这个动态库中的函数其他都是按照流程来,这里需要提一下jpeg_read_scanlines这个函数,jpg其实数据也是RGB 3个字节的数据,但是他的顺序是G B R,相对于bmp是反过来的,所以这里需要注意一下。在读取jpg图像时需要用到jpeg_read_scanlines,这个函数只能一次读取一行,虽然函数说明它是支持多行读取的,但是我改参数为多行会发生段错误,这里原因不明,在程序中我用buffer申请读取一行数据需要的内存大小,读取每行数据到buffer,cinfo.output_scanline会自动加1。其他需要注意的是字节匹配,一定要把所有的数据都读到,不要忘记那三个字节和读取每列时应该乘以行的大小!

下面是实现代码:

#include "../inc/include.h"

int show_jpg(const char *pathname)
{
	unsigned char *buffer;
	unsigned char *jpeg_buff;
	unsigned char *pre_buff;
	int x = 0;
	FILE *infile; 

	/*1.为JPEG对象分配空间并初始化*/
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;

	/*
		将错误处理结构体对象绑定在JPEG对象上
		jpeg_std_error在程序出现错误的时候自动运行exit退出
	 */
	cinfo.err = jpeg_std_error(&jerr);

	/*初始化cinfo结构*/
	jpeg_create_decompress(&cinfo);

	/*2.指定解压缩数据源*/
	if ((infile = fopen(pathname, "r")) == NULL)
	{
		perror("open fail");
		return -1;
	}
	jpeg_stdio_src(&cinfo, infile);

	/*3.获取文件信息*/
	(void)jpeg_read_header(&cinfo, TRUE);
	printf("width = %d, height = %d\n", cinfo.image_width, cinfo.image_height);
	if ((cinfo.image_height != 480) || (cinfo.image_width != 800))
	{
		printf("This jpeg_image is not 800*480,I need change it\n");
	}

	/*4.解压图片,以行为单位*/
	jpeg_start_decompress(&cinfo);

	bzero(lcd, LCD_SIZE);
	usleep(1000);

	/*5.取出数据*/
	int row_stride = cinfo.output_width * cinfo.output_components; //计算每行图像所需的字节大小
	buffer = malloc(row_stride);
	pre_buff = malloc(cinfo.output_width * cinfo.output_components * cinfo.output_height); //很关键,不能少

	while (cinfo.output_scanline < cinfo.output_height)
	{
		(void)jpeg_read_scanlines(&cinfo, (JSAMPARRAY)&buffer, 1);

		for (int i = 0; i < (cinfo.output_width * cinfo.output_components); ++i)
		{
			pre_buff[(cinfo.output_scanline - 1) * cinfo.output_width  * cinfo.output_components + i] = buffer[i];
		}
	}

	//利用最邻近插值进行图像变换
	jpeg_buff = insert_near(pre_buff, cinfo.image_width, cinfo.image_height, 800, 480);
	
	for (int i = 0; i < 480; ++i)
	{
		for (int j = 0, x = 0; j < 800; ++j)
		{
			*(pre_lcd[i] + j) = jpeg_buff[i*800*3 + x] << 16 | jpeg_buff[i*800*3 + x + 1] << 8 | jpeg_buff[i*800*3 + x + 2];
			x += 3;
		}
	}
	

	/*6.解压缩完毕*/
	(void)jpeg_finish_decompress(&cinfo);

	/*7.释放资源*/
	jpeg_destroy_decompress(&cinfo);
	fclose(infile);

	/*8.退出程序*/
	jpeg_destroy_decompress(&cinfo);

	return 0;
}

 

你可能感兴趣的:(专业,JPG,图像缩放,最邻插值算法)