首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Linux中安装libjpeg库(两种应用)

  • 25-03-06 07:00
  • 2843
  • 13413
blog.csdn.net

关于libjpeg库的安装与使用

  • 前言
  • 一、应用于ubuntu
    • 1、下载压缩包(libjpeg源码)
    • 2、解压到某一个目录
    • 3、在这个目录中执行一些操作
    • 4、使用方法
  • 二、应用于嵌入式Linux开发板
    • 1、下载压缩包(同上)
    • 2、解压到某一个目录(同上)
    • 3、在这个目录中执行一些操作(与上面不一样)
    • 4、使用方法

前言

安装这个库的目的,主要是为了将yuv格式的图片文件转换成jpg格式的图片文件。两种应用场景:

一、可能你需要写一个程序,这个程序是放在Ubuntu(x86)上运行的,就将ubuntu上的一些yuv图片转化成jpg图片文件,就可以下载这个libjpeg库,然后去调用这个库中提供的一些函数去实现图片格式的转换。

二、相同的需求,也是需要进行一个图片格式的转换,但是这个转换的程序是放在嵌入式Linux开发板(arm)上面去运行的。

相同功能的程序,放在不同架构的平台去运行

一、应用于ubuntu

1、下载压缩包(libjpeg源码)

通过这个链接下载.tar.gz的压缩包: http://www.ijg.org/
在这里插入图片描述
点击这个压缩包,就会开始下载了…
下载完成之后,就想办法将这个压缩包传到ubuntu中(比如可以使用共享文件夹)

2、解压到某一个目录

在解压之前,你可以在用户目录下,创建一个目录(我创建的目录名是work_pc)用于存放压缩包解压后的文件。紧接着可以去到存放压缩包的目录上去解压了。

tar -zxvf XXX.tar.gz -C [你刚刚创建的空目录的路径]
  • 1

3、在这个目录中执行一些操作

执行完上一步之后,你就cd过去刚刚创建的目录下。你就可以看到一个这样的目录:
在这里插入图片描述
目录名可能你的跟我不一样,因为压缩包内容会更新,更新后名字也会不一样,所以你跟我下载的版本就可能不一样。

接下来cd进去这个目录

进入这个目录之后,输入下面命令,执行该目录下的一个可执行文件:

 ./configure
  • 1

执行完这个命令之后,这个目录中会生成一个Makefile文件(如果不知道这个也没事),紧接着输入下面命令去编译libjpeg源码:

 make
  • 1

编译完成之后就可以安装了,输入下面的命令去安装:

 sudo make install
  • 1

默认安装的路径是在/usr/local/下的,此时你可以过去这个目录下可以看到有个include目录和bin目录和lib目录,如果有下面这些东西,就说明你成功了:
在这里插入图片描述

4、使用方法

使用方法跟应用在嵌入式Linux开发板的方法是一样的,主要区别是在于第3小点的操作不同。

二、应用于嵌入式Linux开发板

1、下载压缩包(同上)

通过这个链接下载.tar.gz的压缩包: http://www.ijg.org/
在这里插入图片描述
点击这个压缩包,就会开始下载了…
下载完成之后,就想办法将这个压缩包传到ubuntu中(比如可以使用共享文件夹)

2、解压到某一个目录(同上)

在解压之前,你可以在用户目录下,创建一个目录(我创建的目录名是work_pc)用于存放压缩包解压后的文件。紧接着可以去到存放压缩包的目录上去解压了。

tar -zxvf XXX.tar.gz -C [你刚刚创建的空目录的路径]
  • 1

3、在这个目录中执行一些操作(与上面不一样)

进来这个目录后,我们需要去执行一个可执行文件./configure,注意,执行这个脚本,我们必须得带上一些参数!

(下面文字是为什么要带参数执行./configure的原因,不想了解可以忽略)

我们的程序是放在开发板上运行,程序是用交叉编译链去编译的,执行这个./configure,会生成一个Makefile文件,里面会记录着要使用的编译器等等信息,如果我们在执行这个./configure时没有带上一些关于交叉编译链的信息,生成的Makefile中的编译器就会默认是Ubuntu中的gcc,等到我们下一步make去编译libjpeg源码的时候,就会编译出只适用于x86架构的东西。此时,你再继续make install安装下来,在你使用的时候就会报错。

(关于动态库,Makefile和链接应用程序等等知识,如果不懂的可以先去了解这方面的知识,才能更好地理解我所述的这些,如果不想了解具体原因,那就跟着步骤做也是可以的)
首先我们的目的是编译出一个动态库,使用这个动态库去链接应用程序,而我们的应用程序是用交叉编译链编译的是用于arm架构,而如果你执行这个脚本不带上参数,就会默认用gcc编译生成一个x86架构的动态库,然后我们再用这个动态库去链接的时候,就会提示我们该文件格式不可识别。


执行下面命令,选定交叉编译链,libjpeg库安装的地方(一些.h文件,一些动态静态库)。

./configure CC=arm-linux-gnueabi-gcc LD=arm-linux-gnueabi-ld --host=arm-linux-gnueabi --prefix=/home/lsc666/tools/buildroot-100ask_t113-pro/buildroot/output/host/opt/ext-toolchain/arm-linux-gnueabi --exec-prefix=/home/lsc666/tools/buildroot-100ask_t113-pro/buildroot/output/host/opt/ext-toolchain/arm-linux-gnueabi --enable-shared --enable-static
  • 1

根据自己的实际情况进行配置:
‘CC=’交叉编译链的名称
‘LD=’链接使用
‘–host=’制定主机(交叉编译链出去gcc的部分即可)
‘–prefix=’头文件存放目录(就是那些.h文件存放的目录,由自己选择)
‘–exec-prefix’库目录存放文件(动态静态库存放的地方)
‘ –enable-shared --enable-static’生成动态,静态链接库。

--prefix与--exec-prefix指定的路径是一样的。

如果看不懂,对照着这个规律,大概大概对着自己的交叉编译链,换一下就好。

执行完上面,紧接着执行下面的命令编译(arm架构)libjpeg源码:

 make
  • 1

最后安装:

 make install
  • 1

安装完成之后,就可以去你上面给定的安装目录(就是你在执行./configure时,传入的参数prefix指定的路径)下,去查看是否有下面这些文件,如果有,就说明成功了。
在这里插入图片描述
在这里插入图片描述

4、使用方法

怎么去用这个库呢,其实方法很简单,就是把jconfig.h、jerror.h、jmorecfg.h、jpeglib.h这四个文件包含进工程目录里面,在将.o文件链接成应用程序的时候,后面带上-ljpeg -L [动态静态库存放的目录路径],就可以了。

比如:

arm-linux-gnueabi-gcc -o main video.o yuv_to_jpeg.o -ljpeg -L [对应存放动态库路径]
  • 1

关于yuyv格式转化成jpg格式的代码部分

#include "yuv_to_jpeg.h"
 
#define OUTPUT_BUF_SIZE  4096
typedef struct 
{
  struct jpeg_destination_mgr pub; /* public fields */
  JOCTET * buffer;    /* start of buffer */
  unsigned char *outbuffer;
  int outbuffer_size;
  unsigned char *outbuffer_cursor;
  int *written;
 
} mjpg_destination_mgr;
typedef mjpg_destination_mgr *mjpg_dest_ptr;
 
/******************************************************************************
函数功能: 初始化输出的目的地
******************************************************************************/
METHODDEF(void) init_destination(j_compress_ptr cinfo) 
{
  mjpg_dest_ptr dest = (mjpg_dest_ptr) cinfo->dest;
 
  /* Allocate the output buffer --- it will be released when done with image */
  dest->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * sizeof(JOCTET));
 
  *(dest->written) = 0;
 
  dest->pub.next_output_byte = dest->buffer;
  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
}
 
/******************************************************************************
函数功能: 当jpeg缓冲区填满时调用
******************************************************************************/
METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo) 
{
  mjpg_dest_ptr dest = (mjpg_dest_ptr) cinfo->dest;
 
  memcpy(dest->outbuffer_cursor, dest->buffer, OUTPUT_BUF_SIZE);
  dest->outbuffer_cursor += OUTPUT_BUF_SIZE;
  *(dest->written) += OUTPUT_BUF_SIZE;
 
  dest->pub.next_output_byte = dest->buffer;
  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
 
  return TRUE;
}
 
/******************************************************************************
函数功能:在写入所有数据之后,由jpeg_finish_compress调用。通常需要刷新缓冲区。
******************************************************************************/
METHODDEF(void) term_destination(j_compress_ptr cinfo) 
{
  mjpg_dest_ptr dest = (mjpg_dest_ptr) cinfo->dest;
  size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
 
  /* Write any data remaining in the buffer */
  memcpy(dest->outbuffer_cursor, dest->buffer, datacount);
  dest->outbuffer_cursor += datacount;
  *(dest->written) += datacount;
}
 
/******************************************************************************
功能描述:初始化输出流
函数参数:
		j_compress_ptr cinfo  :保存JPG图像压缩信息的结构体地址
		unsigned char *buffer :存放压缩之后的JPG图片的缓冲区首地址
		int size              :源图像字节总大小
		int *written          :存放压缩之后的JPG图像字节大小
******************************************************************************/
GLOBAL(void) dest_buffer(j_compress_ptr cinfo, unsigned char *buffer, int size, int *written)
{
  mjpg_dest_ptr dest;
 
  if (cinfo->dest == NULL) {
    cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(mjpg_destination_mgr));
  }
 
  dest = (mjpg_dest_ptr) cinfo->dest;
  dest->pub.init_destination = init_destination;
  dest->pub.empty_output_buffer = empty_output_buffer;
  dest->pub.term_destination = term_destination;
  dest->outbuffer = buffer;
  dest->outbuffer_size = size;
  dest->outbuffer_cursor = buffer;
  dest->written = written;
}
 
/************************************************
功能描述:将YUV格式的数据转为JPG格式。
函数参数:
	int Width    源图像宽度
	int Height   源图像高度
	int size   	 源图像字节总大小
	unsigned char *yuv_buffer :存放YUV源图像数据缓冲区的首地址
	unsigned char *jpg_buffer :存放转换之后的JPG格式数据缓冲区首地址
	int quality               :jpg图像的压缩质量(值越大质量越好,图片就越清晰,占用的内存也就越大)
							一般取值范围是: 10 ~ 100 。 填10图片就有些模糊了,一般的JPG图片都是质量都是80。
返回值:压缩之后的JPG图像大小
**************************************************************/
int yuv_to_jpeg(int Width,int Height,int size,unsigned char *yuv_buffer, unsigned char *jpg_buffer, int quality) 
{
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;
  JSAMPROW row_pointer[1];
  unsigned char *line_buffer, *yuyv;
  int z;
  static int written;
	
  /*1. 解压之前的初始化*/
  line_buffer =(unsigned char *)calloc(Width*3,1);
  yuyv=yuv_buffer; //得到图像源数据
 
  cinfo.err = jpeg_std_error (&jerr);
  jpeg_create_compress (&cinfo);
  
  /* 原版jpeglib库的标准输出初始化函数,只能填文件指针: jpeg_stdio_dest (&cinfo, file); */
  /* 修改之后的标准输出初始化函数,将输出指向内存空间*/
  dest_buffer(&cinfo, jpg_buffer, size, &written);
	
  cinfo.image_width = Width;
  cinfo.image_height =Height;
  cinfo.input_components = 3;
  cinfo.in_color_space = JCS_RGB;
 
  jpeg_set_defaults (&cinfo);
  jpeg_set_quality (&cinfo, quality, TRUE);
 
  jpeg_start_compress (&cinfo, TRUE);
 
  /*2. YUV转RGB格式*/
  z = 0;
  while (cinfo.next_scanline < Height) 
  {
    int x;
    unsigned char *ptr = line_buffer;
 
    for (x = 0; x < Width; x++) {
      int r, g, b;
      int y, u, v;
 
      if (!z)
        y = yuyv[0] << 8;
      else
        y = yuyv[2] << 8;
      u = yuyv[1] - 128;
      v = yuyv[3] - 128;
 
      r = (y + (359 * v)) >> 8;
      g = (y - (88 * u) - (183 * v)) >> 8;
      b = (y + (454 * u)) >> 8;
 
      *(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r);
      *(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g);
      *(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b);
 
      if (z++) {
        z = 0;
        yuyv += 4;
      }
    }
	/*3.进行JPG图像压缩(一行一行压缩)*/
    row_pointer[0] = line_buffer;
    jpeg_write_scanlines(&cinfo, row_pointer, 1);
  }
   
   /*4. 释放压缩时占用的内存空间*/
  jpeg_finish_compress(&cinfo);
  jpeg_destroy_compress(&cinfo);
  free (line_buffer);
  
   /*5. 返回压缩之后JPG图片大小*/
  return (written);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
注:本文转载自blog.csdn.net的点灯学徒的文章"https://blog.csdn.net/qq_62815119/article/details/127709812"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top