嵌入式Linux与ARM开发板——JPEG图片的使用

一、下载源码包

点击这里下载

二、创建安装并解压

mkdir ~/libjpeg
tar -zxvf jpegsrc.v9d.tar.gz

三、移植、编译并安装

cd jpeg-9d/
./configure --host=arm-none-linux-gnueabi --prefix=${HOME}/libjpeg
make
make install

四、图片缩放处理

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <sys/mman.h>
#include "jpeglib.h"     //开发者指定头文件路径
#include <setjmp.h>

int lcd_fd;
int*lcd_ptr;

unsigned char lcd_buf[800*480*4] = {0};

struct my_error_mgr {
  struct jpeg_error_mgr pub;	/* "public" fields */

  jmp_buf setjmp_buffer;	/* for return to caller */
};

typedef struct my_error_mgr * my_error_ptr;

/*
 * Here's the routine that will replace the standard error_exit method:
 */

int lcd_draw_point(int i, int j, int color)
{
	*(lcd_ptr+800*j+i) = color;
}

METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  my_error_ptr myerr = (my_error_ptr) cinfo->err;

  /* Always display the message. */
  /* We could postpone this until after returning, if we chose. */
  (*cinfo->err->output_message) (cinfo);

  /* Return control to the setjmp point */
  longjmp(myerr->setjmp_buffer, 1);
}


/*
 * Sample routine for JPEG decompression.  We assume that the source file name
 * is passed in.  We want to return 1 on success, 0 on error.
 */

// 800 480 400 240 居中
int lcd_draw_jpeg(int x, int y, const char *filename, char *jpeg_buf, int jpeg_size, int zoom_flag)
{
  /* This struct contains the JPEG decompression parameters and pointers to
   * working space (which is allocated as needed by the JPEG library).
   */
  struct stat statbuf;
  struct jpeg_decompress_struct cinfo;
  /* We use our private extension JPEG error handler.
   * Note that this struct must live as long as the main JPEG parameter
   * struct, to avoid dangling-pointer problems.
   */
  struct my_error_mgr jerr;
  int x_c = x;
  /* More stuff */
  
  //FILE * infile;		/* source file */
  JSAMPARRAY buffer;		/* Output row buffer */
  int row_stride;		/* physical row width in output buffer */
  unsigned char *argb_buf = lcd_buf;

  /* In this example we want to open the input file before doing anything else,
   * so that the setjmp() error recovery below can assume the file is open.
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
   * requires it in order to read binary files.
   */
  int img_fd;
  char* img_buf;
  int img_size;

  if (filename != NULL) {
	  int img_fd = open(filename, O_RDWR);

	  if (img_fd == -1) {
	  	  printf("open file failed\n");
	  	  return -1;
	  }

	  fstat(img_fd, &statbuf);

	  img_size = statbuf.st_size;

	  img_buf = calloc(1, img_size);

	  read(img_fd, img_buf, img_size);
  }else {
  	  img_buf = jpeg_buf;
  	  img_size = jpeg_size;
  }

  

  /* Step 1: 分配并初始化jpeg解压对象和错误处理对象 */

  /* We set up the normal JPEG error routines, then override error_exit. */
  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = my_error_exit;
  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp(jerr.setjmp_buffer)) {
    /* If we get here, the JPEG code has signaled an error.
     * We need to clean up the JPEG object, close the input file, and return.
     */
    jpeg_destroy_decompress(&cinfo);
    close(img_fd);
    return 0;
  }
  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress(&cinfo);

  /* Step 2: 指定解压数据源 (eg, 文件) */

  jpeg_mem_src(&cinfo, img_buf, img_size);

  /* Step 3: 读取文件信息数据 */

  (void) jpeg_read_header(&cinfo, TRUE);
  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.txt for more info.
   */

  /* Step 4: 设置解压参数 */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

    /* 缩小一倍*/
	cinfo.scale_num   = 1;
	cinfo.scale_denom = zoom_flag;

	/* 放大一倍
	cinfo.scale_num   = 2;
	cinfo.scale_denom = 1;*/

  /* Step 5: 开始解压 */

  (void) jpeg_start_decompress(&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   * In this example, we need to make an output work buffer of the right size.
   */ 
  /* JSAMPLEs per row in output buffer */
  row_stride = cinfo.output_width * cinfo.output_components;
  /* Make a one-row-high sample array that will go away when done with image */
  buffer = (*cinfo.mem->alloc_sarray)
		((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

		int color, r, g, b, i;

  /* Step 6: 取出数据 */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */
  while (cinfo.output_scanline < cinfo.output_height) {
    /* jpeg_read_scanlines expects an array of pointers to scanlines.
     * Here the array is only one element long, but you could ask for
     * more than one scanline at a time if that's more convenient.
     */
    (void) jpeg_read_scanlines(&cinfo, (JSAMPARRAY)&argb_buf, 1);
    
     for (i = 0; i < cinfo.output_width; i++) {
            b = *(argb_buf+2);
            g = *(argb_buf+1);
            r = *(argb_buf+0);


            //合并
            color = b;
            color |= (g << 8);
            color |= (r << 16);

            lcd_draw_point(x, y, color);

            argb_buf+=3;
            x++;
        }
        y++;
        x = x_c;
  }

  /* Step 7: 完成解压 */

  (void) jpeg_finish_decompress(&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* Step 8: 释放资源 */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress(&cinfo);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  if (filename != NULL) {
     close(img_fd);
  }

  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
   */

  /* And we're done! */
  return 0;
}

int main(void)
{
	//1,打开设备文件
	
	int lcd_fd = open("/dev/fb0", O_RDWR);
	
	//错误处理
	if (lcd_fd == -1) {
		printf("open lcd device failed!\n");
		return -1;
	}
	
	//2,为lcd设备建立内存映射关系
	lcd_ptr = mmap(NULL, 800*480*4, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd, 0);
	
	if (lcd_ptr == MAP_FAILED) {
		printf("mmap failed!\n");
		return -1;
	}

	//lcd_draw_jpeg(起点位置x,起点位置y,图片名字,动态图像数据缓冲区,动态数据的大小,缩放比例);

	//eg : lcd_draw_jpeg(0,0 "1.jpg", NULL, 0, 1);

	//解除映射
	munmap(lcd_ptr, 800*480*4);
	//b 关闭设备文件
	close(lcd_fd);

	return 0;
}

编写完后进行编译运行:

arm-linux-gcc jpeg2lcd.c -o jpeg2lcd -I ~/libjpeg/include/ -L ~/libjpeg/lib -ljpeg

五、扩展

-I(大写i) 指定头文件路径

-L (大写l)指定库文件路径

-l (小写l)链接库文件

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇