鱼C论坛

 找回密码
 立即注册
查看: 39|回复: 2

如何将Mat转为TIF

[复制链接]
发表于 昨天 09:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在C++ MFC中,要将Mat图像转为TIFF图像格式并依赖libtiff库保存为1位深度和1200分辨率的TIF文件应该怎样写代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 09:42 | 显示全部楼层
以下是在C++ MFC环境中,使用OpenCV的Mat和libtiff库将图像转换为1位深度、1200 DPI分辨率TIFF文件的示例代码。请确保已正确安装并链接OpenCV和libtiff库。


  1. #include <opencv2/opencv.hpp>
  2. #include <tiffio.h>

  3. // 函数:将Mat转换为1位深度TIFF
  4. bool MatToTiff1Bit(const cv::Mat& inputMat, const char* filename, int dpi = 1200) {
  5.     // 检查输入图像是否有效
  6.     if (inputMat.empty()) {
  7.         AfxMessageBox(_T("输入图像为空!"));
  8.         return false;
  9.     }

  10.     // 转换为灰度图像(如果原图为彩色)
  11.     cv::Mat grayMat;
  12.     if (inputMat.channels() > 1) {
  13.         cv::cvtColor(inputMat, grayMat, cv::COLOR_BGR2GRAY);
  14.     } else {
  15.         grayMat = inputMat.clone();
  16.     }

  17.     // 二值化处理(转换为1位深度)
  18.     cv::Mat binaryMat;
  19.     cv::threshold(grayMat, binaryMat, 128, 255, cv::THRESH_BINARY);

  20.     // 获取图像尺寸
  21.     int width = binaryMat.cols;
  22.     int height = binaryMat.rows;

  23.     // 打开TIFF文件
  24.     TIFF* tif = TIFFOpen(filename, "w");
  25.     if (!tif) {
  26.         AfxMessageBox(_T("无法创建TIFF文件!"));
  27.         return false;
  28.     }

  29.     // 设置TIFF标签
  30.     TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
  31.     TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
  32.     TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 1);          // 1位深度
  33.     TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);        // 单通道
  34.     TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); // 黑色为0
  35.     TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
  36.     TIFFSetField(tif, TIFFTAG_XRESOLUTION, static_cast<double>(dpi));
  37.     TIFFSetField(tif, TIFFTAG_YRESOLUTION, static_cast<double>(dpi));
  38.     TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  39.     TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, 0));

  40.     // 准备数据缓冲区(每行字节数需按8位对齐)
  41.     int bytesPerLine = (width + 7) / 8;
  42.     std::vector<uint8_t> buffer(bytesPerLine * height, 0);

  43.     // 将二值图像数据打包为1位格式
  44.     for (int y = 0; y < height; y++) {
  45.         const uint8_t* src = binaryMat.ptr<uint8_t>(y);
  46.         uint8_t* dst = &buffer[y * bytesPerLine];
  47.         for (int x = 0; x < width; x++) {
  48.             if (src[x] > 0) {
  49.                 dst[x / 8] |= (1 << (7 - (x % 8))); // 设置对应位为1
  50.             }
  51.         }
  52.     }

  53.     // 写入数据到TIFF
  54.     for (int row = 0; row < height; row++) {
  55.         if (TIFFWriteScanline(tif, &buffer[row * bytesPerLine], row, 0) < 0) {
  56.             TIFFClose(tif);
  57.             AfxMessageBox(_T("写入TIFF数据失败!"));
  58.             return false;
  59.         }
  60.     }

  61.     // 关闭文件并清理
  62.     TIFFClose(tif);
  63.     return true;
  64. }

  65. // 使用示例(在MFC按钮事件中调用)
  66. void CYourDlg::OnBnClickedSaveTiff() {
  67.     cv::Mat matImage = cv::imread("input.png"); // 替换为您的Mat来源
  68.     if (matImage.empty()) {
  69.         AfxMessageBox(_T("加载图像失败!"));
  70.         return;
  71.     }

  72.     CString filePath = _T("output.tif"); // 指定保存路径
  73.     if (MatToTiff1Bit(matImage, CT2A(filePath), 1200)) {
  74.         AfxMessageBox(_T("TIFF保存成功!"));
  75.     } else {
  76.         AfxMessageBox(_T("保存失败!"));
  77.     }
  78. }
复制代码


关键步骤说明:
1. 图像预处理:将输入Mat转换为灰度图,再通过阈值处理二值化。
2. 设置TIFF参数:通过 TIFFSetField 指定1位深度、1200 DPI分辨率等。
3. 数据打包:二值图像每个像素占1位,需按字节对齐并逐位填充。
4. 错误处理:添加基础检查确保操作可靠性。

注意事项:
- 确保项目已链接 opencv_world4xx.liblibtiff.lib
- 分辨率单位默认为英寸(RESUNIT_INCH),1200 DPI通过 XRESOLUTIONYRESOLUTION 设置。
- 二值化阈值设为128,可根据实际图像调整。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 11 小时前 | 显示全部楼层
C++ MFC中使用OpenCV Mat和libtiff库转换:

1. 确保已安装libtiff并链接到项目;

2. 将Mat转换为8位灰度或RGB(如果需要);

3. 使用libtiff函数设置TIFF标签(如分辨率、位深度);

4. 保存为1位深度和1200 DPI。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-10-10 20:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表