libJPEG库是用于编码数据为JPEG格式或者解码JPEG格式图片的常用库,OpenCV读取图像底层实现就是利用libJPEG库,而libJPEG-turbo则效率更高。

具体怎么编译编译libJPEG库源码得到lib库的方法很容易搜到,不多做介绍。

下面的代码包含了该库中常用的API用法,包括读取一幅JPEG图片并解码到内存、编码内存中的数据为JPEG图片写入本地等。

 #include <iostream>
#include <stdio.h>
#include <setjmp.h>
#include <string.h>
#include <stdlib.h>
#include <jpeglib.h>
#include <opencv2/opencv.hpp> using namespace std; int read_JPEG_file(string strImageName)
{
/* This struct contains the JPEG decompression parameters and pointers to
* working space (which is allocated as needed by the JPEG library).
*/
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 jpeg_error_mgr jerr;
/* More stuff */
FILE * infile;/* source file */
JSAMPARRAY buffer;/* Output row buffer */
int row_stride;/* physical row width in output buffer */ /* 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.
*/
if ((infile = fopen(strImageName.c_str(), "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", strImageName);
return -;
} /* Step 1: allocate and initialize JPEG decompression object */
/* We set up the normal JPEG error routines, then override error_exit. */
cinfo.err = jpeg_std_error(&jerr);
/* 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);
//fclose(infile);
//return -1;
//} /* Now we can initialize the JPEG decompression object. */
jpeg_create_decompress(&cinfo); /* Step 2: specify data source (eg, a file) */
jpeg_stdio_src(&cinfo, infile); /* Step 3: read file parameters with jpeg_read_header() */
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.
*/
printf("image_width = %d\n", cinfo.image_width);
printf("image_height = %d\n", cinfo.image_height);
printf("num_components = %d\n", cinfo.num_components); /* Step 4: set parameters for decompression */
/* In this example, we don't need to change any of the defaults set by
* jpeg_read_header(), so we do nothing here.
*/
printf("enter scale M/N:\n");
//scanf("%d/%d", &cinfo.scale_num, &cinfo.scale_denom);
cinfo.scale_num = ;
cinfo.scale_denom = ;
printf("scale to : %d/%d\n", cinfo.scale_num, cinfo.scale_denom); /* Step 5: Start decompressor */
jpeg_start_decompress(&cinfo);
/* We can ignore the return value since suspension is not possible
* with the stdio data source.
*/ //输出的图象的信息
printf("output_width = %d\n", cinfo.output_width);
printf("output_height = %d\n", cinfo.output_height);
printf("output_components = %d\n", cinfo.output_components); /* 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, ); /* Step 6: while (scan lines remain to be read) */
/* 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.
*/
jpeg_read_scanlines(&cinfo, buffer, );
/* Assume put_scanline_someplace wants a pointer and sample count. */
//put_scanline_someplace(buffer[0], row_stride);
} /* Step 7: Finish decompression */
jpeg_finish_decompress(&cinfo);
/* We can ignore the return value since suspension is not possible
* with the stdio data source.
*/ /* Step 8: Release JPEG decompression object */
/* 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...)
*/
fclose(infile); /* At this point you may want to check to see whether any corrupt-data
* warnings occurred (test whether jerr.pub.num_warnings is nonzero).
*/ return ;
} int write_JPEG_file(string strImageName, int quality)
{
unsigned char* image_buffer; /* Points to large array of R,G,B-order data */
int image_height = ; /* Number of rows in image */
int image_width = ; /* Number of columns in image */ /* This struct contains the JPEG compression parameters and pointers to
* working space (which is allocated as needed by the JPEG library).
* It is possible to have several such structures, representing multiple
* compression/decompression processes, in existence at once. We refer
* to any one struct (and its associated working data) as a "JPEG object".
*/
struct jpeg_compress_struct cinfo; /* This struct represents a JPEG error handler. It is declared separately
* because applications often want to supply a specialized error handler
* (see the second half of this file for an example). But here we just
* take the easy way out and use the standard error handler, which will
* print a message on stderr and call exit() if compression fails.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct jpeg_error_mgr jerr;
/* More stuff */
FILE * outfile; /* target file */
JSAMPROW row_pointer[]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */ /* Step 1: allocate and initialize JPEG compression object */ /* We have to set up the error handler first, in case the initialization
* step fails. (Unlikely, but it could happen if you are out of memory.)
* This routine fills in the contents of struct jerr, and returns jerr's
* address which we place into the link field in cinfo.
*/
cinfo.err = jpeg_std_error(&jerr);
/* Now we can initialize the JPEG compression object. */
jpeg_create_compress(&cinfo); /* Step 2: specify data destination (eg, a file) */
/* Note: steps 2 and 3 can be done in either order. */ /* Here we use the library-supplied code to send compressed data to a
* stdio stream. You can also write your own code to do something else.
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to write binary files.
*/
if ((outfile = fopen(strImageName.c_str(), "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", strImageName);
//exit(1);
return -;
}
jpeg_stdio_dest(&cinfo, outfile); /* Step 3: set parameters for compression */
/* First we supply a description of the input image.
* Four fields of the cinfo struct must be filled in:
*/
cinfo.image_width = image_width; /* image width and height, in pixels */
cinfo.image_height = image_height;
cinfo.input_components = ; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
/* Now use the library's routine to set default compression parameters.
* (You must set at least cinfo.in_color_space before calling this,
* since the defaults depend on the source color space.)
*/
jpeg_set_defaults(&cinfo);
/* Now you can set any non-default parameters you wish to.
* Here we just illustrate the use of quality (quantization table) scaling:
*/
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); /* Step 4: Start compressor */
/* TRUE ensures that we will write a complete interchange-JPEG file.
* Pass TRUE unless you are very sure of what you're doing.
*/
jpeg_start_compress(&cinfo, TRUE); /* Step 5: while (scan lines remain to be written) */
/* jpeg_write_scanlines(...); */
/* Here we use the library's state variable cinfo.next_scanline as the
* loop counter, so that we don't have to keep track ourselves.
* To keep things simple, we pass one scanline per call; you can pass
* more if you wish, though.
*/
row_stride = image_width * ; /* JSAMPLEs per row in image_buffer */ image_buffer = new unsigned char[row_stride * cinfo.image_height];
memset(image_buffer, 0xff, row_stride * cinfo.image_height); int line = ;
//while (cinfo.next_scanline < cinfo.image_height) {
while (line < cinfo.image_height) {
/* jpeg_write_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could pass
* more than one scanline at a time if that's more convenient.
*/
//row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride];
row_pointer[] = &image_buffer[line * row_stride];
jpeg_write_scanlines(&cinfo, row_pointer, ); line++;
} delete image_buffer; /* 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 */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_compress(&cinfo); return ;
} struct Image
{
int bpp;
int width;
int height;
unsigned char* data;
}; struct jerror_mgr
{
jpeg_error_mgr base;
jmp_buf jmp;
}; METHODDEF(void) jerror_exit(j_common_ptr jinfo)
{
jerror_mgr* err = (jerror_mgr*)jinfo->err;
longjmp(err->jmp, );
} METHODDEF(void) joutput_message(j_common_ptr)
{
} bool Image_LoadJpeg(Image* image, unsigned char* img_data, unsigned int img_size)
{
jpeg_decompress_struct jinfo;
jerror_mgr jerr; jinfo.err = jpeg_std_error(&jerr.base);
jerr.base.error_exit = jerror_exit;
jerr.base.output_message = joutput_message;
jpeg_create_decompress(&jinfo); image->data = NULL; if (setjmp(jerr.jmp)) goto bail; jpeg_mem_src(&jinfo, img_data, img_size); if (jpeg_read_header(&jinfo, TRUE) != JPEG_HEADER_OK) goto bail; jinfo.dct_method = JDCT_FLOAT; // change this to JDCT_ISLOW on Android/iOS if (!jpeg_start_decompress(&jinfo)) goto bail; if (jinfo.num_components != && jinfo.num_components != ) goto bail; image->data = new (std::nothrow) unsigned char[jinfo.output_width * jinfo.output_height * jinfo.output_components];
if (!image->data) goto bail; {
JSAMPROW ptr = image->data;
while (jinfo.output_scanline < jinfo.output_height)
{
if (jpeg_read_scanlines(&jinfo, &ptr, ) != ) goto bail; ptr += jinfo.output_width * jinfo.output_components;
}
} if (!jpeg_finish_decompress(&jinfo)) goto bail; image->bpp = jinfo.output_components;
image->width = jinfo.output_width;
image->height = jinfo.output_height; jpeg_destroy_decompress(&jinfo); return true; bail:
jpeg_destroy_decompress(&jinfo);
if (image->data) delete[] image->data; return false;
} struct ImageData {
unsigned char *pixels;
long width;
long height;
}; int TestImage(string strSrcImageName, string strDstImageName)
{
//read
struct jpeg_decompress_struct cinfo_decompress;
FILE* infile;
int row_stride;
struct jpeg_error_mgr jerr; if ((infile = fopen(strSrcImageName.c_str(), "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", strSrcImageName);
return -;
} cinfo_decompress.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo_decompress);
jpeg_stdio_src(&cinfo_decompress, infile);
int ret = jpeg_read_header(&cinfo_decompress, TRUE);
if (ret != JPEG_HEADER_OK) return -;
jpeg_start_decompress(&cinfo_decompress);
row_stride = cinfo_decompress.output_width * cinfo_decompress.output_components;
int buffer_height = ;
JSAMPARRAY buffer = (JSAMPARRAY)malloc(sizeof(JSAMPROW) * buffer_height);
buffer[] = (JSAMPROW)malloc(sizeof(JSAMPLE) * row_stride);
//JSAMPARRAY buffer = (*cinfo_decompress.mem->alloc_sarray)((j_common_ptr)&cinfo_decompress, JPOOL_IMAGE, row_stride, 1);
ImageData *imageData;
imageData = new ImageData;
imageData->width = cinfo_decompress.output_width;
imageData->height = cinfo_decompress.output_height; imageData->pixels = new unsigned char[cinfo_decompress.output_width * cinfo_decompress.output_height * cinfo_decompress.output_components];
long counter = ; while (cinfo_decompress.output_scanline < cinfo_decompress.output_height) {
jpeg_read_scanlines(&cinfo_decompress, buffer, );
memcpy(imageData->pixels + counter, buffer[], row_stride);
counter += row_stride;
} jpeg_finish_decompress(&cinfo_decompress);
jpeg_destroy_decompress(&cinfo_decompress); fclose(infile); //write
unsigned char* image_buffer;
int image_height = cinfo_decompress.output_height;
int image_width = cinfo_decompress.output_width;
FILE * outfile;
JSAMPROW row_pointer[];
int row_stride_dst;
struct jpeg_compress_struct cinfo_compress;
cinfo_compress.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo_compress); if ((outfile = fopen(strDstImageName.c_str(), "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", strDstImageName);
//exit(1);
return -;
} jpeg_stdio_dest(&cinfo_compress, outfile); cinfo_compress.image_width = image_width;
cinfo_compress.image_height = image_height;
cinfo_compress.input_components = ;
cinfo_compress.in_color_space = JCS_EXT_RGB; int quality = ;
jpeg_set_defaults(&cinfo_compress);
jpeg_set_quality(&cinfo_compress, quality, TRUE);
jpeg_start_compress(&cinfo_compress, TRUE); row_stride_dst = image_width * ; image_buffer = new unsigned char[row_stride_dst * cinfo_compress.image_height];
memcpy(image_buffer, imageData->pixels, row_stride_dst * cinfo_compress.image_height); while (cinfo_compress.next_scanline < cinfo_compress.image_height) {
row_pointer[] = &image_buffer[cinfo_compress.next_scanline * row_stride_dst];
jpeg_write_scanlines(&cinfo_compress, row_pointer, );
} jpeg_finish_compress(&cinfo_compress);
fclose(outfile);
jpeg_destroy_compress(&cinfo_compress); if (imageData) {
delete imageData;
imageData = NULL;
} if (image_buffer)
delete[] image_buffer; return ;
} int main(int argc, char* argv[])
{
string strImageName = "data/srcImg/moon.jpg";
int flag1 = read_JPEG_file(strImageName);
if (flag1 == ) cout << "read ok!" << endl;
else cout << "read error!" << endl; strImageName = "2.bmp";
int flag2 = write_JPEG_file(strImageName, );
if (flag2 == ) cout << "write ok!" << endl;
else cout << "write error!" << endl; string strSrcImageName = "data/srcImg/moon.jpg";
string strDstImageName = "b.jpg";
int flag3 = TestImage(strSrcImageName, strDstImageName);
if (flag3 == ) cout << "test ok!" << endl;
else cout << "test error!" << endl; return ;
}

libJPEG-turbo库使用示例代码的更多相关文章

  1. C/C++ 开源库及示例代码

    C/C++ 开源库及示例代码 Table of Contents 说明 1 综合性的库 2 数据结构 & 算法 2.1 容器 2.1.1 标准容器 2.1.2 Lockfree 的容器 2.1 ...

  2. 1.NetDh框架之数据库操作层--Dapper简单封装,可支持多库实例、多种数据库类型等(附源码和示例代码)

    1.NetDh框架开始的需求场景 需求场景: 1.之前公司有不同.net项目组,有的项目是用SqlServer做数据库,有的项目是用Oracle,后面也有可能会用到Mysql等,而且要考虑后续扩展成主 ...

  3. AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码

    目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告 AIR32F103(二) Linux环境和LibOpenCM3项目模板 AIR32F103(三) Linux环境基于标准外 ...

  4. gRaphael——JavaScript 矢量图表库:两行代码实现精美图表

    gRaphael 是一个致力于帮助开发人员在网页中绘制各种精美图表的 Javascript 库,基于强大的 Raphael 矢量图形库.你只需要编写几行简单的代码就能创建出精美的条形图.饼图.点图和曲 ...

  5. 微软发布手机版 Sample Browser。7000多示例代码一手掌握

    今天早上,Sample Browser发布其全新的Windows Phone版本.至此,自2012年相继推出Desktop版.Visual Studio版,以及2013年推出Windows Store ...

  6. 一个非常标准的Java连接Oracle数据库的示例代码

    最基本的Oracle数据库连接代码(只针对Oracle11g): 1.右键项目->构建路径->配置构建路径,选择第三项“库”,然后点击“添加外部Jar”,选择“D:\Oracle\app\ ...

  7. python开源项目及示例代码

    本页面是俺收集的各种 Python 资源,不定期更新. 下面列出的各种 Python 库/模块/工具,如果名称带超链接,说明是第三方的:否则是 Python 语言内置的. 1 算法 1.1 字符串处理 ...

  8. Java连接Oracle数据库的示例代码

    最基本的Oracle数据库连接代码(只针对Oracle11g): 1.右键项目->构建路径 ->配置构建路径,选择第三项“库”,然后点击“添加外部Jar”,选择 “D:\Oracle\ap ...

  9. iOS App集成Apple Pay教程(附示例代码)

    苹果在本周一发布了iOS 8.1版本,并正式开放了Apple Pay支付系统.Apple Pay是一个基于NFC的支付系统,不久将被数以万计的线下零售商店予以支持.即便这项科技并不是彻底的突破性进展, ...

随机推荐

  1. 再谈javascript面向对象编程

    前言:虽有陈皓<Javascript 面向对象编程>珠玉在前,但是我还是忍不住再画蛇添足的补上一篇文章,主要是因为javascript这门语言魅力.另外这篇文章是一篇入门文章,我也是才开始 ...

  2. 命令行执行Django脚本的方法

    update.py import os import sys import django sys.path.append(r'C:\Users\Administrator\PycharmProject ...

  3. .Net IOC框架入门之二 CastleWindsor

    一.简介 Castle是.net平台上的一个开源项目,为企业级开发和WEB应用程序开发提供完整的服务,用于提供IOC的解决方案.IOC被称为控制反转或者依赖注入(Dependency Injectio ...

  4. Java实现矩阵计算器【代码】

    其实这个程序最开始是大二下学期Java的一次平时作业,当时只要求产生几个随机矩阵并对这些矩阵进行计算. 所以当时没去实现现在这么丰富而且实用的功能.不过当时倒是挺想去做的,无奈有些不知道怎么去实现. ...

  5. Java的成员变量初始化

    对于方法里面的成员变量,Java要求程序员强制提供一个初始化的值.比如下面这个方法就会出错: public class Breakyizhan{ public void Z(){ int z; z++ ...

  6. 公众号的Markdown排版利器:Md2All

    微信公众号:颜家大少如有问题或建议,请公众号留言 本文所用排版工具:Md2All,http://md.aclickall.com 公众号排版工具 公众号的排版编辑工具还真的不少,但功能大同小异,大部分 ...

  7. c/c++中static的详解

    C 语言的 static 关键字有三种(具体来说是两种)用途: 1. 静态局部变量:用于函数体内部修饰变量,这种变量的生存期长于该函数. int foo(){ ; // note:1 //int i ...

  8. 虚拟机迁移(QEMU动态迁移,Libvirt动(静)态迁移)

    动静态迁移的原理 静态迁移是指在虚拟机关闭或暂停的情况下,将源宿主机上虚拟机的磁盘文件和配置文件拷贝到目标宿主机上.这种方式需要显式的停止虚拟机运行,对服务可用性要求高的需求不合适. *** 动态迁移 ...

  9. Redis Sentinel配置小记

    Sentinel是一个管理多个redis实例的工具,它可以实现对redis的监控.通知.自动故障转移.sentinel不断的检测redis实例是否可以正常工作,通过API向其他程序报告redis的状态 ...

  10. Talking appsettings.json in Asp.Net Core

    在ASP.NET Core中,默认提供了三个运行时环境变量,通过查看Hosting源代码我们可以看到,分别是Development.Staging.Production public static c ...