LCD显示JPEG图片

JPEG图片

JPEG文件:经压缩,不仅空间能缩小挺多,而且图片质量损失不太明显,被广泛应用。

jpeglib库

配置编译:

  1. ./configure --host=arm-linux
  2. make
  3. make DESTDIR=$PWD/tmp install
  4. 将指定的库文件和头文件拷贝到交叉编译工具对应目录下
把编译出来的头文件应该放入:/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include

把编译出来的动态库文件应该放入:/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib 以及 arm根文件系统的lib目录下

关键实现思路

打开jpeg,获取其文件描述符的对应信息cinfo,根据其成员可得到该Jpeg一行数据的大小row_stride = cinfo.output_width * cinfo.output_components,申请一段空间,将该行数据解压后存放于该空间中,解压后的数据用以描述一个像素点的字节数由num_components可知,一般为3字节,分别表示RGB,每次解压都将一行的RGB数据存放于对应空间中,并将3字节大小的RGB数据通过错位相加888格式存储于unsigned int color变量中,通过该color值,写入FB对应位置中,显示出来。

即读一行,显示一行,循环一直往下读,到底部。

使用

  1. 分配和初始化一个decompression结构体
	struct jpeg_decompress_struct cinfo;
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);
  1. 打开LCD Fb对应的设备结点,并将其空间共享到用户空间中,即可在内存中进行操作
	g_fd = open(FB_DEVICE_NAME, O_RDWR);
	
	ret = ioctl(g_fd, FBIOGET_VSCREENINFO, &g_tFBVar);
	ret = ioctl(g_fd, FBIOGET_FSCREENINFO, &g_tFBFix);

	g_dwScreenSize = g_tFBVar.xres * g_tFBVar.yres * g_tFBVar.bits_per_pixel / 8;
	g_pucFBMem = (unsigned char *)mmap(NULL , g_dwScreenSize, PROT_READ | PROT_WRITE,MAP_SHARED, g_fd, 0);
  1. 指定jpeg源文件
	FILE *infile = fopen(argv[1], "rb");
	jpeg_stdio_src(&cinfo, infile);
  1. 用jpeg_read_header获得jpg信息,num_components一般为3,表示分别表示RGB值
	jpeg_read_header(&cinfo, TRUE);
	/* 源信息 */
	printf("image_width = %d\n", cinfo.image_width);
	printf("image_height = %d\n", cinfo.image_height);
	printf("num_components = %d\n", cinfo.num_components);
  1. 设置解压参数,比如放大、缩小; 注意:该步骤可能不成功,需要对比解压前后的参数确定。
	printf("enter scale M/N:\n");
	scanf("%d/%d", &cinfo.scale_num, &cinfo.scale_denom);
	printf("scale to : %d/%d\n", cinfo.scale_num, cinfo.scale_denom);
  1. 启动解压:
	jpeg_start_decompress(&cinfo);
	/* 输出的图象的信息 */
	printf("output_width = %d\n", cinfo.output_width);
	printf("output_height = %d\n", cinfo.output_height);
	printf("output_components = %d\n", cinfo.output_components);
  1. 分配一段内存空间,用于获取解压后一行的数据
	// 一行的数据长度
	row_stride = cinfo.output_width * cinfo.output_components;
	buffer = malloc(row_stride);
  1. 循环调用,一行一行获取并显示到LCD
	while (cinfo.output_scanline < cinfo.output_height) 
	{
		(void) jpeg_read_scanlines(&cinfo, &buffer, 1);

		// 写到LCD去
		FBShowLine(0, cinfo.output_width, cinfo.output_scanline, buffer);
	}
  1. 释放存储解压数据的内存:free(buffer);

  2. 完成解压:jpeg_finish_decompress

  3. 释放decompression结构体:jpeg_destroy_decompress(&cinfo);

FBshowline

static int FBShowLine(int iXStart, int iXEnd, int iY, unsigned char *pucRGBArray)
{
	int i = iXStart * 3;
	int iX;
	unsigned int dwColor;

	if (iY >= g_tFBVar.yres)
		return -1;

	if (iXStart >= g_tFBVar.xres)
		return -1;

	if (iXEnd >= g_tFBVar.xres)
	{
		iXEnd = g_tFBVar.xres;		
	}
	
	for (iX = iXStart; iX < iXEnd; iX++)
	{
		/* 0xRRGGBB */
		dwColor = (pucRGBArray[i]<<16) + (pucRGBArray[i+1]<<8) + (pucRGBArray[i+2]<<0);
		i += 3;
		FBShowPixel(iX, iY, dwColor);
	}
	return 0;
}

FBShowPixel

static int FBShowPixel(int iX, int iY, unsigned int dwColor)
{
	unsigned char *pucFB;
	unsigned short *pwFB16bpp;
	unsigned int *pdwFB32bpp;
	unsigned short wColor16bpp; /* 565 */
	int iRed;
	int iGreen;
	int iBlue;

	if ((iX >= g_tFBVar.xres) || (iY >= g_tFBVar.yres))
	{
		DBG_PRINTF("out of region\n");
		return -1;
	}

	pucFB      = g_pucFBMem + g_dwLineWidth * iY + g_dwPixelWidth * iX;
	pwFB16bpp  = (unsigned short *)pucFB;
	pdwFB32bpp = (unsigned int *)pucFB;
	
	switch (g_tFBVar.bits_per_pixel)
	{
		case 8:
		{
			*pucFB = (unsigned char)dwColor;
			break;
		}
		case 16:
		{
			iRed   = (dwColor >> (16+3)) & 0x1f;
			iGreen = (dwColor >> (8+2)) & 0x3f;
			iBlue  = (dwColor >> 3) & 0x1f;
			wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;
			*pwFB16bpp	= wColor16bpp;
			break;
		}
		case 32:
		{
			*pdwFB32bpp = dwColor;
			break;
		}
		default :
		{
			DBG_PRINTF("can't support %d bpp\n", g_tFBVar.bits_per_pixel);
			return -1;
		}
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值