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

20250713 保存 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.lryc.cn/news/586900.html

相关文章:

  • COZE token刷新
  • 一文读懂现代卷积神经网络—使用块的网络(VGG)
  • 2025江苏省信息安全管理与评估赛项二三阶段任务书
  • 改进后的 OpenCV 5.x + GStreamer + Python 3.12 编译流程(适用于 Orange Pi / ARM64)
  • 3.7 ASPICE的问题解决与改进过程
  • Linux-网络管理
  • iTestin 自动化录制工具
  • Kimi K2深度解析:开源万亿参数大模型,复杂场景能力强悍,为AI Agent而生!
  • Vision Kit之文档扫描
  • 【PyMuPDF】PDF图片处理过程内存优化分析
  • 论文Review 3DGSSLAM GauS-SLAM: Dense RGB-D SLAM with Gaussian Surfels
  • kettle从入门到精通 第102课 ETL之kettle xxl-job调度kettle的两种方式
  • 归并排序递归法和非递归法的简单简单介绍
  • 三种网络类型
  • X00211-基于残差edge-graph注意力机制的深度强化学习优化车辆路径问题
  • RedisJSON 技术揭秘(五)`JSON.ARRPOP` 原子弹出 修改数组的终极手段
  • 基于Java Web的销售管理系统设计系统
  • 操作系统--用户态和内核态
  • MongoDB对接SpringBoot【大数据存储】
  • ref 和 reactive
  • https交互原理
  • [Subtitle Edit] 字幕格式处理 | .Net依赖管理(NuGet)
  • Python----OpenCV(图像分割——彩色图像分割,GrabCut算法分割图像)
  • LeetCode--44.通配符匹配
  • Mybatis 两级缓存可能导致的问题
  • Java4种设计模式详解(单例模式、工厂模式、适配器模式、代理模式)
  • 笔记/sklearn中的数据划分方法
  • 赛力斯6月新能源汽车销量46086辆,同比增长4.44%
  • JavaScript加强篇——第九章 正则表达式高级应用(终)
  • Linux编程:6、进程通信-信号量与共享内存