【编译构建】用cmake编译libjpeg动态库并实现转灰度图片

先编译出libjepg动态库

1、下载libjpeg源码:

https://github.com/libjpeg-turbo/libjpeg-turbo

2、编译出动态库或静态库

写一个编译脚本,用cmake构建。

#!/bin/bash# 定义变量
SOURCE_DIR="/home/user/libjpeg-turbo-main"
BUILD_DIR="${SOURCE_DIR}/build"
INSTALL_DIR="/home/user/libjpeg-turbo-main"# 创建并进入构建目录
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"# 运行CMake命令
cmake -G"Unix Makefiles" \-DCMAKE_BUILD_TYPE=Release \-DWITH_MEM_SRCDST=1 \-DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \"$SOURCE_DIR"# 编译和安装
make -j$(nproc)
sudo make install# 提示完成
echo "Build and installation completed successfully!"

chmod +x ./libjpeg_build.sh
./libjpeg_build.sh
run!
编译生成的动态库安装在libjpeg-turbo-main/lib目录下 。
在这里插入图片描述

3、写代码

动态库有两种加载方式,一种编译的时候就依赖,一种是运行的时候dlopen。
写一个代码用turbo提供的接口实现一个彩色图片转灰度的图片的demo。

3.1 编译的时候就依赖

写CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(libjpeg_demo)set(JPEG_LIB_DIR "/home/user/libjpeg-turbo-main/lib")
set(JPEG_INCLUDE_DIR "/home/user/libjpeg-turbo-main/include")include_directories(${JPEG_INCLUDE_DIR})
link_directories(${JPEG_LIB_DIR})add_executable(libjpeg_demo main.cpp)
target_link_libraries(libjpeg_demo turbojpeg)

cpp代码

#include <turbojpeg.h>
#include <iostream>
#include <fstream>
#include <vector>void saveGrayscaleImage(const std::string &filename, const unsigned char* buffer, int width, int height) {std::ofstream outFile(filename, std::ios::binary);outFile << "P5\n" << width << " " << height << "\n255\n";outFile.write(reinterpret_cast<const char*>(buffer), width * height);outFile.close();
}int main() {const char* inputFile = "1.jpg";tjhandle jpegDecompressor = tjInitDecompress();std::ifstream inFile(inputFile, std::ios::binary | std::ios::ate);if (!inFile) {std::cerr << "Error: Could not open input file!" << std::endl;return 1;}std::streamsize fileSize = inFile.tellg();inFile.seekg(0, std::ios::beg);std::vector<unsigned char> jpegBuffer(fileSize);inFile.read(reinterpret_cast<char*>(jpegBuffer.data()), fileSize);int width, height, jpegSubsamp;tjDecompressHeader2(jpegDecompressor, jpegBuffer.data(), fileSize, &width, &height, &jpegSubsamp);std::vector<unsigned char> grayscaleBuffer(width * height);tjDecompress2(jpegDecompressor, jpegBuffer.data(), fileSize, grayscaleBuffer.data(), width, 0, height, TJPF_GRAY, TJFLAG_FASTDCT);saveGrayscaleImage("grayscale.pgm", grayscaleBuffer.data(), width, height);tjDestroy(jpegDecompressor);std::cout << "Grayscale image saved as grayscale.pgm" << std::endl;return 0;
}
3.2 通过dlopen动态加载

写CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(libjpeg_dl_demo)set(CMAKE_CXX_STANDARD 17)add_executable(libjpeg_dl_demo main.cpp)
target_link_libraries(libjpeg_dl_demo dl)
#include <dlfcn.h>
#include <iostream>
#include <fstream>
#include <vector>
#include "turbojpeg.h"// 定义动态加载的函数指针类型
typedef void* tjhandle;
typedef tjhandle (*tjInitDecompress_t)();
typedef int (*tjDecompressHeader2_t)(tjhandle, unsigned char*, unsigned long, int*, int*, int*);
typedef int (*tjDecompress2_t)(tjhandle, unsigned char*, unsigned long, unsigned char*, int, int, int, int, int);
typedef int (*tjDestroy_t)(tjhandle);// 保存灰度图像为 PGM 格式
void saveGrayscaleImage(const std::string &filename, const unsigned char* buffer, int width, int height) {std::ofstream outFile(filename, std::ios::binary);outFile << "P5\n" << width << " " << height << "\n255\n";outFile.write(reinterpret_cast<const char*>(buffer), width * height);outFile.close();
}int main() {const char* inputFile = "/home/user/demo/1.jpg";  // 输入文件路径// 动态加载 libturbojpeg.so 库void* handle = dlopen("/home/user/libjpeg-turbo-main/lib/libturbojpeg.so.0.4.0", RTLD_LAZY);if (!handle) {std::cerr << "Error loading tjInitDecompress: " << dlerror() << std::endl;return 1;}// 获取函数指针auto tjInitDecompress = (tjInitDecompress_t)dlsym(handle, "tjInitDecompress");auto tjDecompressHeader2 = (tjDecompressHeader2_t)dlsym(handle, "tjDecompressHeader2");auto tjDecompress2 = (tjDecompress2_t)dlsym(handle, "tjDecompress2");auto tjDestroy = (tjDestroy_t)dlsym(handle, "tjDestroy");if (!tjInitDecompress || !tjDecompressHeader2 || !tjDecompress2 || !tjDestroy) {std::cerr << "Error: Failed to load necessary functions from libturbojpeg.so" << std::endl;dlclose(handle);return 1;}// 初始化解压器tjhandle jpegDecompressor = tjInitDecompress();if (!jpegDecompressor) {std::cerr << "Error: Failed to initialize decompressor" << std::endl;dlclose(handle);return 1;}// 打开输入文件std::ifstream inFile(inputFile, std::ios::binary | std::ios::ate);if (!inFile) {std::cerr << "Error: Could not open input file!" << std::endl;tjDestroy(jpegDecompressor);dlclose(handle);return 1;}// 读取 JPEG 文件内容std::streamsize fileSize = inFile.tellg();inFile.seekg(0, std::ios::beg);std::vector<unsigned char> jpegBuffer(fileSize);inFile.read(reinterpret_cast<char*>(jpegBuffer.data()), fileSize);// 解压 JPEG header 获取图像尺寸int width, height, jpegSubsamp;if (tjDecompressHeader2(jpegDecompressor, jpegBuffer.data(), fileSize, &width, &height, &jpegSubsamp) != 0) {std::cerr << "Error: Failed to read JPEG header" << std::endl;tjDestroy(jpegDecompressor);dlclose(handle);return 1;}// 解压 JPEG 为灰度图像std::vector<unsigned char> grayscaleBuffer(width * height);if (tjDecompress2(jpegDecompressor, jpegBuffer.data(), fileSize, grayscaleBuffer.data(), width, 0, height, TJPF_GRAY, 0) != 0) {std::cerr << "Error: Failed to decompress image to grayscale" << std::endl;tjDestroy(jpegDecompressor);dlclose(handle);return 1;}// 保存灰度图像为 PGM 格式saveGrayscaleImage("grayscale.pgm", grayscaleBuffer.data(), width, height);// 清理资源并关闭库tjDestroy(jpegDecompressor);dlclose(handle);std::cout << "Grayscale image saved as grayscale.pgm" << std::endl;return 0;
}

写完
cd build
cmake …
make
./libjpeg_dl_demo
跑起来啦
ok~

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ORB-SLAM2源码学习: Frame.cc: cv::Mat Frame::UnprojectStereo将某个特征点反投影到三维世界坐标系中

前言 这个函数是在跟踪线程中更新上一帧的函数中被调用。 1.函数声明 cv::Mat Frame::UnprojectStereo(const int &i) 2.函数定义 1.获取这个特征点的深度值。 const float z mvDepth[i];深度值由双目或 RGB-D 传感器获取。 在双目情况下&#xff0c;这个深度来自…

单片机存储器和C程序编译过程

1、 单片机存储器 只读存储器不是并列关系&#xff0c;是从ROM发展到FLASH的过程 RAM ROM 随机存储器 只读存储器 CPU直接存储和访问 只读可访问不可写 临时存数据&#xff0c;存的是CPU正在使用的数据 永久存数据&#xff0c;存的是操作系统启动程序或指令 断电易失 …

【Excel】【VBA】双列排序:坐标从Y从大到小排列之后相同Y坐标的行再对X从小到大排列

Excel VBA 双列排序 功能概述 这段VBA代码实现了Excel中的双列排序功能&#xff0c;具体是&#xff1a; 跳过前3行表头先按C列数据从大到小排序在C列值相同的情况下&#xff0c;按B列从大到小排序排序时保持整行数据的完整性 流程图 #mermaid-svg-XJERemQluZlM4K8l {font-fa…

【25考研】西南交通大学软件工程复试攻略!

一、复试内容 复试对考生的既往学业情况、外语听说交流能力、专业素质和科研创新能力&#xff0c;以及综合素质和一贯表现等进行全面考查,主要考核内容包括思想政治素质和道德品质、外语听说能力、专业素质和能力&#xff0c;综合素质及能力。考核由上机考试和面试两部分组成&a…

运行fastGPT 第四步 配置ONE API 添加模型

上次已经装好了所有的依赖和程序。 下面在网页中配置One API &#xff0c;这个是大模型的接口。配置好了之后&#xff0c;就可以配置fastGPT了。 打开 OneAPI 页面 添加模型 这里要添加具体的付费模型的API接口填进来。 可以通过ip:3001访问OneAPI后台&#xff0c;**默认账号…

硬件知识:显示器发展历程介绍

目录 一、阴极射线管显示器(CRT) 二、等离子显示器(PDP) 三、液晶显示器(LCD) 四、传统LED显示器(LED) 五、有机发光二极管显示器(OLED) 六、量子点显示器(QD) 七、MiniLED显示器(MiniLED) 八、MicroLED显示器(MicroLED) 总结 显示器作为电子设备与人…

修复5.0.0r 64位版本浏览器和一些库找不到的问题

笔者在使用5.0.0r版本64位时踩过不少坑&#xff0c;先将相关修复方法分享 浏览器无法使用 base/startup/appspawn/appdata-sandbox64.json添加沙箱配置 相关修复pr:https://gitee.com/openharmony/startup_appspawn/pulls/1854/files {"src-path" : "/system…

【Flink系列】4. Flink运行时架构

4. Flink运行时架构 4.1 系统架构 Flink运行时架构——Standalone会话模式为例 1&#xff09;作业管理器&#xff08;JobManager&#xff09; JobManager是一个Flink集群中任务管理和调度的核心&#xff0c;是控制应用执行的主进程。也就是说&#xff0c;每个应用都应该被…

IP层之分片包的整合处理

前言 在上一章节中&#xff0c;笔者就IP层的接收代码逻辑做了简单介绍&#xff0c;并对实现代码进行了逻辑梳理以及仿真测试&#xff0c;并且在上一章节中&#xff0c;就IP层的分片包问题&#xff0c;如何确定分片包是否存在已经进行了简单介绍&#xff0c;并在接收模块中&…

使用jupyter notebook没有正常打开浏览器的几种情况解决

迅速记录前期 1.下载 https://www.anaconda.com/products/individual 2.安装 直接默认安装就行 3.打开jupyter notebook 在开始菜单里面可以找到 4.遇到的问题解决 1.运行jupyter notebook&#xff0c;黑窗口自动关了 每次黑窗口迅速的加载完就自己关掉了 也没有打开新…

50.【8】BUUCTF WEB HardSql

进入靶场 随便输输 上order by ????????&#xff0c;被过滤了,继续找其他也被过滤的关键字 #&#xff0c;-- -&#xff0c;-- 都不行&#xff0c;尝试其他特殊字符后发现and&#xff0c;union&#xff0c;select&#xff0c;空格&#xff0c;都被过滤了 如下 我就不知…

中国石油大学(华东)自动评教工具(涵盖爬虫的基础知识,适合练手)

我开发了一个用于自动评教的工具&#xff0c;大家可以试着用用&#xff0c;下面是链接。 https://github.com/restrain11/auto_teachingEvaluate 可以点个星吗&#xff0c;感谢&#xff01;&#x1fae1; 以下是我在开发过程中学到的知识 以及 碰到的部分问题 目录 动态爬虫和静…

深入云电脑PC Farm技术探讨,以阿里云、华为云、ToDesk为例

&#x1f31d;引言 近年来&#xff0c;云计算技术的飞速发展为各行各业的数字化转型带来了全新机遇&#xff0c;其中云电脑作为一种虚拟化桌面解决方案&#xff0c;逐渐成为个人用户与企业的核心选择。从远程办公、在线教育到高性能计算需求&#xff0c;云电脑通过为用户提供随…

RK3568平台(音频篇)lineout无声调试

一.声音硬件框架 硬件HP_MUTE已强制拉低。 二.设备树配置 es8388_sound: es8388-sound {status = "okay";compatible = "rockchip,multicodecs-card";rockchip,card-name = "rockchip-es8388";hp-det-gpio = <&gpio1 RK_PD2 GPIO_ACT…

docker 部署 MantisBT

1. docker 安装MantisBT docker pull vimagick/mantisbt:latest 2.先运行实例&#xff0c;复制配置文件 docker run -p 8084:80 --name mantisbt -d vimagick/mantisbt:latest 3. 复制所需要配置文件到本地路径 docker cp mantisbt:/var/www/html/config/config_inc.php.…

【Linux】Mysql部署步骤

一、JDK安装配置 在home目录下执行命令&#xff1a;mkdir Jdk 1.将JDK 上传至该文件夹&#xff0c;有些终端工具可以直接上传文件&#xff0c;比如&#xff1a;MobaXterm 可以看到安装包已经上传上来了 2.直接安装 命令&#xff1a;rpm -ivh jdk-8u311-linux-x64.rpm 3.安装成…

静态综合路由实验

实验拓扑 实验要求 1.除R5的环回地址外&#xff0c;整个其他所有网段基于192.168.1.0/24进行合理的IP地址划分 2.R1-R4每个路由器存在两个环回接口&#xff0c;用于模拟pc网段&#xff1b;地址也在192.168.1.0/24这个网络范围内 3.R1-R4上不能直接编写到达5.5.5.0/24的静态路由…

Unity ShaderGraph中Lit转换成URP的LitShader

ShaderGraph中的LitShader如下&#xff1a; 在顶点和片元着色器暴露出了上图中的几个参数&#xff0c;要转换成URPLitShaderLab,首先要找到这几个参数&#xff0c;打开LitShader&#xff0c;找到第一个Pass&#xff0c;可以看到下图中的顶点和片元的定义函数&#xff0c;还有引…

从漏洞管理到暴露管理:网络安全的新方向

在网络安全的快速发展中&#xff0c;传统的漏洞管理仍然是防御体系的基石。然而&#xff0c;面对日益复杂的威胁和不断增长的漏洞数量&#xff0c;单靠漏洞优先级评分&#xff08;如VPR&#xff09;已经无法满足现代安全需求。暴露管理这一全新的思维模式正在引领企业从被动应对…

中职网络建设与运维ansible服务

ansible服务 填写hosts指定主机范围和控制节点后创建一个脚本&#xff0c;可以利用简化脚本 1. 在linux1上安装系统自带的ansible-core,作为ansible控制节点,linux2-linux7作为ansible的受控节点 Linux1 Linux1-7 Yum install ansible-core -y Vi /etc/ansible/hosts 添加…