LibJPEG库使用_通过LibJPEG将RGB数据保存为JPG图片存储到磁盘

一、前言

LibJPEG库是一个广泛使用的开源C库,用于处理JPEG图像的压缩和解压缩。该库由独立JPEG小组(Independent JPEG Group, IJG)开发,提供了功能强大的API,用于创建和读取JPEG文件。LibJPEG库支持JPEG的所有常见功能,包括高质量的压缩、解压缩、图像处理、颜色空间转换等。采用DCT(离散余弦变换)算法实现了高效的图像压缩,同时支持各种图像质量的调整。LibJPEG的灵活性和性能使其成为图像处理应用中的标准工具,被广泛应用于图像编辑软件、图像查看器、图像传输等多个领域。该库跨平台兼容,支持Windows、Linux、macOS等操作系统,开发者可以轻松将其集成到不同的平台和应用中。LibJPEG库还具有良好的文档支持,提供详细的编程指南和示例代码,帮助开发者快速上手和实现复杂的图像处理功能。由于其开源性质和广泛的应用,LibJPEG在业界享有很高的声誉,成为许多图像处理项目的首选库。

LibJPEG库的源码下载地址:https://www.ijg.org/

image-20240808164050380

下载后是一个ZIP的压缩包,解压看到的数据:

image-20240808162923658

如果要下载编译好的二进制文件,可以去这里下载:https://gnuwin32.sourceforge.net/packages/jpeg.htm

image-20240808163240331

二、函数接口解释

LibJPEG库提供了一组函数接口,用于实现JPEG图像的压缩和解压缩操作。

以下是一些常用的LibJPEG库函数接口及其详细讲解,包括函数功能、参数作用等。

2.1 JPEG压缩相关函数

jpeg_create_compress
  • 功能:初始化JPEG压缩对象。

  • 参数

    • struct jpeg_compress_struct *cinfo:指向JPEG压缩对象的指针。

  • 说明:必须在进行任何其他JPEG压缩操作之前调用该函数。

jpeg_stdio_dest
  • 功能:设置压缩数据的目标为标准I/O流。

  • 参数

    • struct jpeg_compress_struct *cinfo:指向JPEG压缩对象的指针。

    • FILE *outfile:目标文件的文件指针。

  • 说明:指定JPEG数据输出的目标文件。

jpeg_set_defaults
  • 功能:设置JPEG压缩参数的默认值。

  • 参数

    • struct jpeg_compress_struct *cinfo:指向JPEG压缩对象的指针。

  • 说明:设置一组默认的JPEG压缩参数。

jpeg_set_quality
  • 功能:设置JPEG压缩质量。

  • 参数

    • struct jpeg_compress_struct *cinfo:指向JPEG压缩对象的指针。

    • int quality:压缩质量,范围为0(最差)到100(最佳)。

    • boolean force_baseline:如果为TRUE,强制生成符合JPEG标准的文件。

  • 说明:调整JPEG压缩的质量参数。

jpeg_start_compress
  • 功能:启动压缩过程。

  • 参数

    • struct jpeg_compress_struct *cinfo:指向JPEG压缩对象的指针。

    • boolean write_all_tables:如果为TRUE,写入所有JPEG标记。

  • 说明:在压缩数据之前调用该函数。

jpeg_write_scanlines
  • 功能:写入压缩数据行。

  • 参数

    • struct jpeg_compress_struct *cinfo:指向JPEG压缩对象的指针。

    • JSAMPARRAY scanlines:指向存储图像数据的缓冲区。

    • JDIMENSION num_lines:要写入的行数。

  • 说明:写入图像数据到JPEG压缩对象中。

jpeg_finish_compress
  • 功能:完成压缩过程。

  • 参数

    • struct jpeg_compress_struct *cinfo:指向JPEG压缩对象的指针。

  • 说明:在完成所有数据写入后调用,关闭JPEG压缩对象。

jpeg_destroy_compress
  • 功能:销毁JPEG压缩对象。

  • 参数

    • struct jpeg_compress_struct *cinfo:指向JPEG压缩对象的指针。

  • 说明:释放JPEG压缩对象分配的所有资源。

2.2 JPEG解压缩相关函数

jpeg_create_decompress
  • 功能:初始化JPEG解压缩对象。

  • 参数

    • struct jpeg_decompress_struct *cinfo:指向JPEG解压缩对象的指针。

  • 说明:必须在进行任何其他JPEG解压缩操作之前调用该函数。

jpeg_stdio_src
  • 功能:设置解压数据的源为标准I/O流。

  • 参数

    • struct jpeg_decompress_struct *cinfo:指向JPEG解压缩对象的指针。

    • FILE *infile:源文件的文件指针。

  • 说明:指定JPEG数据输入的源文件。

jpeg_read_header
  • 功能:读取JPEG文件的头部信息。

  • 参数

    • struct jpeg_decompress_struct *cinfo:指向JPEG解压缩对象的指针。

    • boolean require_image:如果为TRUE,要求图像数据存在。

  • 说明:读取JPEG文件的头部信息,解析JPEG图像的元数据。

jpeg_start_decompress
  • 功能:启动解压缩过程。

  • 参数

    • struct jpeg_decompress_struct *cinfo:指向JPEG解压缩对象的指针。

  • 说明:在解压缩数据之前调用该函数。

jpeg_read_scanlines
  • 功能:读取解压缩的数据行。

  • 参数

    • struct jpeg_decompress_struct *cinfo:指向JPEG解压缩对象的指针。

    • JSAMPARRAY scanlines:指向存储解压缩数据的缓冲区。

    • JDIMENSION max_lines:要读取的最大行数。

  • 说明:从JPEG解压缩对象中读取图像数据。

jpeg_finish_decompress
  • 功能:完成解压缩过程。

  • 参数

    • struct jpeg_decompress_struct *cinfo:指向JPEG解压缩对象的指针。

  • 说明:在完成所有数据读取后调用,关闭JPEG解压缩对象。

jpeg_destroy_decompress
  • 功能:销毁JPEG解压缩对象。

  • 参数

    • struct jpeg_decompress_struct *cinfo:指向JPEG解压缩对象的指针。

  • 说明:释放JPEG解压缩对象分配的所有资源。

2.3 辅助函数

jpeg_std_error
  • 功能:初始化JPEG错误处理对象。

  • 参数

    • struct jpeg_error_mgr *err:指向JPEG错误处理对象的指针。

  • 说明:设置默认的JPEG错误处理例程。

这些函数共同构成了LibJPEG库的核心接口,通过它们可以实现JPEG图像的高效压缩和解压缩。在使用这些函数时,需要按照特定的调用顺序来确保正确的操作和资源管理。

三、代码实现

以下是将RGB565图像转换为RGB888并压缩为JPEG格式的完整示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <jpeglib.h>
​
// 将RGB565转换为RGB888
void RGB565_to_RGB888(uint16_t rgb565, uint8_t *r, uint8_t *g, uint8_t *b) {*r = ((rgb565 >> 11) & 0x1F) << 3;*g = ((rgb565 >> 5) & 0x3F) << 2;*b = (rgb565 & 0x1F) << 3;
}
​
// 将RGB565格式图像转换为RGB888格式
void convert_RGB565_to_RGB888(const uint8_t *rgb565_image, uint8_t *rgb888_image, int width, int height) {for (int i = 0; i < width * height; i++) {uint16_t rgb565 = ((uint16_t)rgb565_image[2 * i + 1] << 8) | rgb565_image[2 * i];RGB565_to_RGB888(rgb565, &rgb888_image[3 * i], &rgb888_image[3 * i + 1], &rgb888_image[3 * i + 2]);}
}
​
// 将RGB888格式图像压缩为JPEG格式
void compress_to_JPEG(const uint8_t *rgb888_image, int width, int height, const char *filename) {struct jpeg_compress_struct cinfo;struct jpeg_error_mgr jerr;
​FILE *outfile;JSAMPROW row_pointer[1];int row_stride;
​cinfo.err = jpeg_std_error(&jerr);jpeg_create_compress(&cinfo);
​if ((outfile = fopen(filename, "wb")) == NULL) {fprintf(stderr, "can't open %s\n", filename);exit(1);}jpeg_stdio_dest(&cinfo, outfile);
​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, 75, TRUE);jpeg_start_compress(&cinfo, TRUE);
​row_stride = width * 3;
​while (cinfo.next_scanline < cinfo.image_height) {row_pointer[0] = (JSAMPROW) &rgb888_image[cinfo.next_scanline * row_stride];jpeg_write_scanlines(&cinfo, row_pointer, 1);}
​jpeg_finish_compress(&cinfo);fclose(outfile);jpeg_destroy_compress(&cinfo);
}
​
int main() {// 假设图像尺寸为100x100int width = 100;int height = 100;
​// 示例RGB565数据uint8_t rgb565_image[20000];for (int i = 0; i < 20000; i++) {rgb565_image[i] = rand() % 256; // 用随机数据填充}
​// 分配RGB888图像数据的内存uint8_t *rgb888_image = (uint8_t *)malloc(width * height * 3);if (rgb888_image == NULL) {fprintf(stderr, "Unable to allocate memory for RGB888 image\n");return 1;}
​// 转换RGB565到RGB888convert_RGB565_to_RGB888(rgb565_image, rgb888_image, width, height);
​// 压缩并保存为JPEG文件compress_to_JPEG(rgb888_image, width, height, "output.jpg");
​// 释放内存free(rgb888_image);
​printf("Compression to JPEG completed.\n");
​return 0;
}
​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148932.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

哈希——字符串哈希

回顾/本期梗概 上期我们学习了图论基础&#xff08;空降链接&#xff09;&#xff0c;本期我们将学习哈希中的字符串哈希。 1、什么是哈希 哈希算法是&#xff1a;通过哈希函数讲字符串、较大的数等转换为能够用变量表示的或者是直接能作为数组下标的数&#xff0c;通过哈希算法…

基于MT79815G CPE 板子上挂usb3.0的5G 模块,WIFI能跑多少速度呢

关于MT79815G CPE 板子上挂usb3.0的5G 模块&#xff0c;WIFI能跑多少速度的问题&#xff0c;我们以启明智显 ZX7981P智能无线接入型路由器&#xff08;CPE&#xff09;挂广合通5G模组为例说明&#xff1a; 一般来说&#xff0c;用 ZX7981P&#xff0c;通过软加速&#xff0c;U…

专业120+总分400+中国科学技术大学843信号与系统考研经验中科大电子信息通信工程,生物医学工程,苏医工,真题,大纲,参考书。

经过将近一年的复习备考&#xff0c;专业843信号与系统120&#xff0c;总分400&#xff0c;顺利上岸朝思暮想的中科大。总结一些自己的备考经验&#xff0c;希望能给大家一些参考&#xff0c;少走弯路。首先讲一下大家最关注的专业课&#xff1a;843信号与系统 中科大843专业课…

kafka集群架构与原理

前言 这次我们从消息队列开始讨论。生产者-消费者模型中间需要一个消息队列&#xff0c;以存储生产者的产品。对传统的消息队列来说&#xff0c;它支持点对点&#xff08;P2P&#xff09;和发布/订阅&#xff08;Pub/Sub&#xff09;两种消息模型。在点对点模型中&#xff0c;消…

OpenCV_自定义线性滤波(filter2D)应用详解

OpenCV filter2D将图像与内核进行卷积&#xff0c;将任意线性滤波器应用于图像。支持就地操作。当孔径部分位于图像之外时&#xff0c;该函数根据指定的边界模式插值异常像素值。 卷积核本质上是一个固定大小的系数数组&#xff0c;数组中的某个元素被作为锚点&#xff08;一般…

使用vite+react+ts+Ant Design开发后台管理项目(四)

前言 本文将引导开发者从零基础开始&#xff0c;运用vite、react、react-router、react-redux、Ant Design、less、tailwindcss、axios等前沿技术栈&#xff0c;构建一个高效、响应式的后台管理系统。通过详细的步骤和实践指导&#xff0c;文章旨在为开发者揭示如何利用这些技术…

SAP B1 认证考试习题 - 基础主数据(解析版)

感谢投喂*罒▽罒* 一、基础 1. 下列哪个产品不是以中小型企业为目标客户的 A. mySAP All-in-One B. SAP Business One C. mySAP Business Suite 答案&#xff1a;C 解析&#xff1a;SAP Business One -- 为小型企业定制的解决方案&#xff08;250人以下&#xff09;&…

【论文】FunAudioLLM:一个旨在增强人类与大型语言模型(LLMs)之间自然语音交互的模型家族

研究背景 1.研究问题&#xff1a;这篇文章要解决的问题是如何增强人类与大型语言模型&#xff08;LLMs&#xff09;之间的自然语音交互。具体来说&#xff0c;研究集中在语音识别、情感识别和音频事件检测&#xff08;多语言&#xff09;以及语音生成&#xff08;多语言、零样…

Python模拟真人鼠标轨迹

一.API跨语言平台支持 鼠标轨迹API 底层实现采用 C/C 语言&#xff0c;利用其高性能和系统级访问能力&#xff0c;开发出高效的鼠标轨迹模拟算法。通过将算法封装为 DLL&#xff08;动态链接库&#xff09;&#xff0c;可以方便地在不同的编程环境中调用&#xff0c;实现跨语言…

【C++】容器适配器,stack,queue,priority_queue详解,模拟实现

目录 1. stack和queue的介绍 1.1 stack的成员函数 1.2 queue的成员函数 1.3 stack的使用 1.4 queue的使用 1.5 Container模板参数&#xff0c;deque 2. priority_queue优先级队列的介绍 3. stack模拟实现 3.1 初始结构 3.2 push 3.3 pop 3.4 top 3.5 empty 3.6 s…

C++笔试强训15、16、17

文章目录 笔试强训15一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训16一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训17一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训15 一、选择题 1-5题 共有派生下&#xff0c;派生类的成员函数只能访问基类的…

揭秘智能派单流程:如何利用AI实现高效的自动化任务分配?

前言 在当今的企业管理和服务行业中&#xff0c;高效的工作分配与任务管理是提升企业竞争力的重要因素。智能派单流程通过结合先进的算法和人工智能技术&#xff0c;实现了工作任务的自动化分配和优化管理&#xff0c;不仅帮助企业提升了工作效率&#xff0c;降低了运营成本&a…

Kubernetes强制删除terminating状态的namespace

Kubernetes中的Namespace处于Terminating状态并且常规删除不起作用。 1.Namespace长时间处于Terminating状态往往是因为某些finalizers阻止了它的删除。 kubectl get namespace <namespace-name> -o json > namespace.json 2.编辑生成的 namespace.json文件&#xff…

在 Vue 3 中实现“折叠”与“展开”文本内容

偶然间遇到一个场景&#xff0c;怎么判断一段文本是否超过 5 行或者指定行数&#xff0c;并在超过时显示 "展开/收起" 按钮。那应该如何实现呢&#xff1f; 在 Vue 3 的项目下实现&#xff1a; <template><div class"text-container"><di…

计算机毕业设计 学院网站系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Java框架学习(Spring)(ioc)(01)

简介&#xff1a;以本片记录在尚硅谷学习ssm-spring-ioc时遇到的小知识 详情移步&#xff1a;想参考的朋友建议全部打开相互配合学习&#xff01; 视频&#xff1a; 014-spring-框架概念理解_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1AP411s7D7?p14&vd_sou…

【楚怡杯】职业院校技能大赛 “云计算应用” 赛项样题九

某企业根据自身业务需求&#xff0c;实施数字化转型&#xff0c;规划和建设数字化平台&#xff0c;平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”&#xff0c;拟采用开源OpenStack搭建企业内部私有云平台&#xff0c;开源Kubernetes搭建云原生服务平台&#xff0c;选…

GIS留学院校介绍-英国篇

看前须知 关于语言成绩要求&#xff1a; 通常英国院校的雅思成绩要求分为5个等级&#xff0c;标准分别如下&#xff1a; 1级&#xff1a;总分6.5分&#xff0c;每个部分最低6.0分 2级&#xff1a;总分7.0&#xff0c;每个部分至少6.5分 3级&#xff1a;总分7.0分&#xff…

2024年有什么开放式耳机推荐?盘点开放式蓝牙耳机排行榜前五名

​到了2024年&#xff0c;开放式耳机无疑成为了耳机市场的宠儿。它们的优势在于&#xff0c;不仅佩戴舒适&#xff0c;还能在保护听力的同时&#xff0c;让你保持对周围环境的警觉&#xff0c;这对于爱好户外探险的朋友来说&#xff0c;无疑是一个巨大的安全加分项。作为一名资…

(附源码)微信小程序的拼车设计-计算机毕设19413

微信小程序的拼车设计 摘 要 在微信小程序的拼车服务中&#xff0c;后端架构巧妙地运用了SSM&#xff08;Spring、SpringMVC、MyBatis&#xff09;框架&#xff0c;为用户带来了流畅、高效的体验。Spring框架作为整个系统的核心&#xff0c;不仅管理着业务逻辑&#xff0c;还通…