当前位置: 首页 > news >正文

20250713 保存 PBM / PGM / PPM 图片 C++

测试结果

在这里插入图片描述

直接上代码

-std=c++17,记得编译时指定 C++17,创建文件夹的时候要用。不需要创建文件夹可以去掉。

// *********************************************
// Brief: save image as ppm, pbm, pgm
// Note:
// P1 - PBM_ASCII,  P2 - PGM_ASCII,  P3 - PPM_ASCII,
// P4 - PBM_BINARY, P5 - PGM_BINARY, P6 - PPM_BINARY
//
// Date:   13 Jul 2025
// *********************************************
#include <vector>
#include <iostream>
#include <filesystem>static void createPath(const std::string &fullPath)
{std::filesystem::path filePath(fullPath);// get filename without extensionstd::string filename = filePath.stem().string();// create new pathstd::filesystem::path dirPath = filePath.parent_path();// / filename;// create folderif (std::filesystem::exists(dirPath)){} else if (std::filesystem::create_directories(dirPath)){printf("Create Folder Success: %s\n", dirPath.c_str());} else{printf("Create Folder Failed, might already exists: %s\n", dirPath.c_str());}
}/*** PBM - Portable BitMap, 0 - White, 1 - Black**/
static void saveImgAsPBM(const std::string &dumpPath, uint8_t *data, size_t width, size_t height)
{// PBM is an image format, can open with default image viewer on ubuntu.std::string flow_ppm_filename = dumpPath + ".pbm";createPath(flow_ppm_filename);FILE *pOutFile = NULL;pOutFile = fopen(flow_ppm_filename.c_str(), "wb");fprintf(pOutFile, "P4\n");fprintf(pOutFile, "%ld %ld\n", (long) width, (long) height);// fprintf(pOutFile, "1\n");   // no max value for PBM// packing image data, MSB firstconst size_t rowBytes = (width + 7) / 8;std::vector<uint8_t> packed(rowBytes);for (size_t y = 0; y < height; ++y){std::fill(packed.begin(), packed.end(), 0); // clear bufferfor (size_t x = 0; x < width; ++x){const size_t byteIdx = x / 8;const size_t bitPos  = 7 - (x % 8);  // MSB firstif (data[y * width + x]){packed[byteIdx] |= (1 << bitPos);}}// write into filefwrite(packed.data(), 1, rowBytes, pOutFile);}fclose(pOutFile);
}/*** PGM - Portable GreyMap, 0 - Black, MaxNum - White*/
static void saveImgAsPGM(const std::string &dumpPath, uint8_t *data, size_t width, size_t height)
{// PGM is an image format, can open with default image viewer on ubuntu.std::string flow_ppm_filename = dumpPath + ".pgm";createPath(flow_ppm_filename);FILE *pOutFile = NULL;pOutFile = fopen(flow_ppm_filename.c_str(), "wb");fprintf(pOutFile, "P5\n");fprintf(pOutFile, "%ld %ld\n", (long) width, (long) height);fprintf(pOutFile, "255\n"); // set max value to 255fwrite(data, 1, 1 * width * height, pOutFile);fclose(pOutFile);
}/*** PPM - Portable PixMap*/
static void saveImgAsPPM(const std::string &dumpPath, uint8_t *data, size_t width, size_t height)
{// PPM is an image format, can open with default image viewer on ubuntu.std::string flow_ppm_filename = dumpPath + ".ppm";createPath(flow_ppm_filename);FILE *pOutFile = NULL;pOutFile = fopen(flow_ppm_filename.c_str(), "wb");fprintf(pOutFile, "P6\n");fprintf(pOutFile, "%ld %ld\n", (long) width, (long) height);fprintf(pOutFile, "255\n");fwrite(data, 1, 3 * width * height, pOutFile);fclose(pOutFile);
}int main() {const size_t width = 256;const size_t height = 256;const std::string basePath = "./output/test_image";// 1. PBM teststd::vector<uint8_t> pbmData(width * height, 1);for (size_t y = 0; y < height; ++y) {for (size_t x = 0; x < width; ++x) {pbmData[y * width + x] = (x / 16 + y / 16) % 2; // checkerboard pattern}}saveImgAsPBM(basePath + "_pbm", pbmData.data(), width, height);std::cout << "PBM Test finished.\n";// 2. PGM teststd::vector<uint8_t> pgmData(width * height);for (size_t y = 0; y < height; ++y) {for (size_t x = 0; x < width; ++x) {pgmData[y * width + x] = x % 256; // gradient}}saveImgAsPGM(basePath + "_pgm", pgmData.data(), width, height);std::cout << "PGM Test finished.\n";// 3. PPM teststd::vector<uint8_t> ppmData(3 * width * height);for (size_t y = 0; y < height; ++y) {for (size_t x = 0; x < width; ++x) {size_t pos = 3 * (y * width + x);ppmData[pos] = x % 256;       // R, gradient valueppmData[pos + 1] = y % 256;   // G, gradient valueppmData[pos + 2] = 128;       // B}}saveImgAsPPM(basePath + "_ppm", ppmData.data(), width, height);std::cout << "PPM Test finished.\n";return 0;
}

Refference

  • DeepSeek 内容
    • Main 函数编写
    • PBM Packing 代码实现
  • PPM、PGM、PBM三种都是图像文件格式
    在这里插入图片描述
  • PBM Packing 原理
    在这里插入图片描述
http://www.dtcms.com/a/278137.html

相关文章:

  • 拼写纠错模型Noisy Channel(上)
  • 中华心法问答系统的解读(1)
  • XCZU2CG-2SFVC784I Xilinx FPGA AMD Zynq UltraScale+ MPSoC
  • if-constexpr,编译报错expected a “(“
  • JavaScript 中一些常见算法的实现及详细解析
  • 问题 E: Connecting Territories(DP)
  • 理解volatile:并发编程的核心机制
  • 能说说MyBatis的工作原理吗?
  • 柯西不等式
  • CATIA许可价格高,设计部门如何精细化分配?
  • 【时时三省】(C语言基础)通过指针引用数组元素2
  • 未来航空电子系统
  • 浮点数的乘法与除法运算耗时对比
  • 洛谷 P13014:[GESP202506 五级] 最大公因数
  • 基于python的栅格数据标准差椭圆
  • Can201-Introduction to Networking:Transport Layer 传输层
  • 跨领域科学探索智能体设计与实现
  • 模块化编程为何使用函数指针分析(一)(深入分析指针的实际应用)
  • 【uniapp】元胞自动机GameOfLife生命游戏项目开发流程详解
  • Java SE--图书管理系统模拟实现
  • 模型占用显存大小评估
  • 【AI大模型】ComfyUI:Stable Diffusion可视化工作流
  • java基础编程(入门)
  • C++多线程知识点梳理
  • 深入理解 Java Map 与 Set
  • 每天学一个八股(二)——详解HashMap
  • 封装---优化try..catch错误处理方式
  • 【echarts踩坑记录】为什么第二个Y轴最大值不整洁
  • Acrobat 表单中的下拉菜单(附示例下载)
  • 使用docker的常用命令