鱼C论坛

 找回密码
 立即注册
查看: 629|回复: 9

关于TIF图片处理问题

[复制链接]
发表于 2024-11-17 11:42:50 | 显示全部楼层 |阅读模式

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

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

x
下面的代码可以将bmp24位图片进行膨胀处理,但仅限于bmp格式和24位色彩模式,请问怎样修改它才能让它直接处理TIF格式的1位色彩模式,或者8位色彩模式的二值图,因为图片比较大的时侯 photoshop没办法保存为bmp格式,只能保存为TIF格式

  1. #include "pch.h"
  2. #include "framework.h"
  3. #include "TTS.h"
  4. #include "TTSDlg.h"
  5. #include "afxdialogex.h"

  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #endif
  9. #pragma warning(disable:4996);//出现fopen错误使用此代码

  10. void CTTSDlg::OnBnClickedButton1()
  11. {
  12.         int        m_nWidth;                //图像实际宽度
  13.         int        m_nHeight;                //图像实际高度
  14.         int        m_nDrawWidth;        //图像显示宽度
  15.         int        m_nDrawHeight;        //图像显示高度
  16.         DWORD m_nImage;                //图像数据的字节数 只含位图
  17.         DWORD m_nSize;      //图像文件大小
  18.         int m_nLineByte;    //图像一行所占字节数
  19.         int        m_nBitCount;    //图像每个像素所占位数
  20.         int        m_nPalette;     //位图实际使用的颜色表中的颜色数
  21.         CBitmap m_bitmaplin;   //创建临时位图对象进行处理
  22.         CString BmpNameLin;    //保存图像副本文件

  23.         BYTE* m_pImage;         //读入图片数据后的指针
  24.         BITMAPFILEHEADER bfh;   //全局变量文件头
  25.         BITMAPINFOHEADER bih;   //全局变量信息头

  26.         FILE* fp = fopen("test1.bmp", "rb");
  27.         if (fp == 0)
  28.         {
  29.                 AfxMessageBox(_T("无法打开文件!"), MB_OK, 0);
  30.                 return;
  31.         }
  32.         //读取文件头 解决BMP格式倒置的方法
  33.         fread(&bfh.bfType, sizeof(WORD), 1, fp);
  34.         fread(&bfh.bfSize, sizeof(DWORD), 1, fp);
  35.         fread(&bfh.bfReserved1, sizeof(WORD), 1, fp);
  36.         fread(&bfh.bfReserved2, sizeof(WORD), 1, fp);
  37.         fread(&bfh.bfOffBits, sizeof(DWORD), 1, fp);
  38.         //图像文件的总字节数
  39.         m_nSize = bfh.bfSize;
  40.         //判断是否是bmp格式图片
  41.         if (bfh.bfType != 0x4d42)   //'BM'
  42.         {
  43.                 AfxMessageBox(_T("不是BMP格式图片!"), MB_OK, 0);
  44.                 return;
  45.         }
  46.         //读取信息头
  47.         fread(&bih.biSize, sizeof(DWORD), 1, fp);
  48.         fread(&bih.biWidth, sizeof(LONG), 1, fp);
  49.         fread(&bih.biHeight, sizeof(LONG), 1, fp);
  50.         fread(&bih.biPlanes, sizeof(WORD), 1, fp);
  51.         fread(&bih.biBitCount, sizeof(WORD), 1, fp);
  52.         fread(&bih.biCompression, sizeof(DWORD), 1, fp);
  53.         fread(&bih.biSizeImage, sizeof(DWORD), 1, fp);
  54.         fread(&bih.biXPelsPerMeter, sizeof(LONG), 1, fp);
  55.         fread(&bih.biYPelsPerMeter, sizeof(LONG), 1, fp);
  56.         fread(&bih.biClrUsed, sizeof(DWORD), 1, fp);
  57.         fread(&bih.biClrImportant, sizeof(DWORD), 1, fp);
  58.         if (bih.biSize != sizeof(bih))
  59.         {
  60.                 AfxMessageBox(_T("本结构所占用字节数出现错误"));
  61.                 return;
  62.         }
  63.         //位图压缩类型,必须是 0(不压缩) 1(BI_RLE8压缩类型)或2(BI_RLE压缩类型)之一
  64.         if (bih.biCompression == BI_RLE8 || bih.biCompression == BI_RLE4)
  65.         {
  66.                 AfxMessageBox(_T("位图被压缩!"));
  67.                 return;
  68.         }
  69.         //获取图像高宽和每个像素所占位数
  70.         m_nHeight = bih.biHeight;
  71.         m_nWidth = bih.biWidth;
  72.         m_nDrawHeight = bih.biHeight;
  73.         m_nDrawWidth = bih.biWidth;
  74.         m_nBitCount = bih.biBitCount;   //每个像素所占位数
  75.         //计算图像每行像素所占的字节数(必须是32的倍数)
  76.         m_nLineByte = (m_nWidth * m_nBitCount + 31) / 32 * 4;
  77.         //图片大小 调用系统自带的文件头 BITMAPFILEHEADER bfh; BITMAPINFOHEADER bih;
  78.         //否则用 BITMAPFILEHEADER_ bfh; BITMAPINFOHEADER_ bih;要 m_nImage = m_nLineByte * m_nHeight - 2;
  79.         m_nImage = m_nLineByte * m_nHeight;
  80.         //位图实际使用的颜色表中的颜色数 biClrUsed
  81.         m_nPalette = 0;                       //初始化
  82.         if (bih.biClrUsed)
  83.                 m_nPalette = bih.biClrUsed;
  84.         //申请位图空间 大小为位图大小 m_nImage
  85.         //malloc只能申请4字节的空间 (未知)
  86.         m_pImage = (BYTE*)malloc(m_nImage);

  87.         int num;//记录每一行需要填充的字节
  88.         if (m_nWidth * 3 % 4 != 0)
  89.         {
  90.                 num = 4 - m_nWidth * 3 % 4;
  91.         }
  92.         else
  93.         {
  94.                 num = 0;
  95.         }

  96.         //打开临时的图片  
  97.         FILE* fpw = fopen("output.bmp", "wb+");
  98.         fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, fpw);
  99.         fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, fpw);
  100.         fread(m_pImage, m_nImage, 1, fp);
  101.         unsigned char* ImageSize;
  102.         ImageSize = new unsigned char[m_nImage];
  103.         int x, y, val, xx, yy, temp;
  104.         for (y = 1; y < m_nHeight - 1; y++)
  105.         {
  106.                 for (x = 1; x < m_nWidth - 1; x++)//由于使用3*3的结构元素,防止越界,不处理最左边和最右边的的像素
  107.                 {
  108.                         val = 0;
  109.                         for (int j = 0; j < 2; j++)
  110.                         {
  111.                                 yy = y + j - 1;
  112.                                 for (int i = 0; i < 2; i++)
  113.                                 {
  114.                                         xx = x + i - 1;
  115.                                         if (m_pImage[(xx + yy * m_nWidth) * 3 + yy * num] > val)//因为结构元素都是0,所以原图像中各点与对应结构元素想加还是原图像本身,
  116.                                                 //找和的最大值作为点(x,y)的灰度
  117.                                         {
  118.                                                 val = m_pImage[(xx + yy * m_nWidth) * 3 + yy * num];
  119.                                         }
  120.                                 }
  121.                         }
  122.                         ImageSize[(x + y * m_nWidth) * 3 + y * num] = unsigned char(val);
  123.                         ImageSize[(x + y * m_nWidth) * 3 + y * num + 1] = unsigned char(val);
  124.                         ImageSize[(x + y * m_nWidth) * 3 + y * num + 2] = unsigned char(val);
  125.                 }
  126.         }

  127.         fwrite(ImageSize, m_nImage, 1, fpw);

  128.         fclose(fp);
  129.         fclose(fpw);
  130. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-17 11:42:58 | 显示全部楼层
要修改代码以处理TIF格式的1位或8位色彩模式的二值图,可以使用OpenCV库来简化操作。主要思路是通过OpenCV读取TIF文件并进行膨胀处理,最终将结果保存回TIF文件。以下是修改后的代码:

首先,确保在项目中配置了OpenCV库。

  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>

  3. void processTif() {
  4.     // 使用OpenCV读取TIF图像
  5.     cv::Mat image = cv::imread("input.tif", cv::IMREAD_UNCHANGED);

  6.     if(image.empty()) {
  7.         std::cout << "无法打开文件!" << std::endl;
  8.         return;
  9.     }

  10.     // 确保图像是8位或1位二值图
  11.     if(image.type() != CV_8UC1 && image.type() != CV_8UC3) {
  12.         std::cout << "图像类型不兼容!" << std::endl;
  13.         return;
  14.     }

  15.     // 创建一个膨胀操作的结构元素 (3x3)
  16.     cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

  17.     cv::Mat result;
  18.     // 对图像进行膨胀操作
  19.     cv::dilate(image, result, element);

  20.     // 保存处理后的图像
  21.     if(!cv::imwrite("output.tif", result)) {
  22.         std::cout << "保存图像失败!" << std::endl;
  23.     }
  24. }

  25. int main() {
  26.     processTif();
  27.     return 0;
  28. }
复制代码


### 说明:

1. **OpenCV库**: 使用OpenCV可以方便地处理多种格式的图像,包括TIF,并支持对一位或八位图像进行处理。

2. **cv::imread和cv::imwrite**: 分别用于读取和保存图像文件。`cv::IMREAD_UNCHANGED`确保读取的图像不受默认颜色转换的影响。

3. **cv::dilate**: 使用膨胀操作对图像进行处理,具体操作由`cv::getStructuringElement`函数定义的结构元素决定。

通过这种方式,处理图像的复杂度大大降低,并可以避免手动处理文件头、内存分配等低级细节。

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

使用道具 举报

 楼主| 发表于 2024-11-17 11:45:06 | 显示全部楼层
FishC 发表于 2024-11-17 11:42
要修改代码以处理TIF格式的1位或8位色彩模式的二值图,可以使用OpenCV库来简化操作。主要思路是通过OpenCV ...

排除opencv方法,因为opencv方式打开特别大的图片时很费时间,所以想使用现在这种方式
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-17 11:45:17 | 显示全部楼层
cxnet 发表于 2024-11-17 11:45
排除opencv方法,因为opencv方式打开特别大的图片时很 ...


如果你想通过现有的方式读取和处理TIF格式的图像,而不依赖OpenCV,可以考虑使用libtiff库。libtiff是一个专门用于处理TIFF文件格式的库,可以高效读取和写入TIFF图像。

下面是一个如何使用libtiff来读取和处理TIF文件的示例代码,假设你已经安装并配置了libtiff:

  1. #include <tiffio.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>

  4. void processTIFF(const char* inputFileName, const char* outputFileName) {
  5.     TIFF* tif = TIFFOpen(inputFileName, "r");
  6.     if (tif) {
  7.         uint32 width, height;
  8.         size_t npixels;
  9.         uint32* raster;

  10.         TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  11.         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  12.         npixels = width * height;
  13.         raster = (uint32*)_TIFFmalloc(npixels * sizeof(uint32));

  14.         if (raster != NULL) {
  15.             if (TIFFReadRGBAImage(tif, width, height, raster, 0)) {
  16.                 // 膨胀操作
  17.                 for (uint32 y = 1; y < height - 1; y++) {
  18.                     for (uint32 x = 1; x < width - 1; x++) {
  19.                         // 获取像素值,进行膨胀
  20.                         uint32 maxVal = 0;
  21.                         for (int j = -1; j <= 1; j++) {
  22.                             for (int i = -1; i <= 1; i++) {
  23.                                 uint32 currentVal = raster[(y + j) * width + (x + i)];
  24.                                 if (currentVal > maxVal) {
  25.                                     maxVal = currentVal;
  26.                                 }
  27.                             }
  28.                         }
  29.                         raster[y * width + x] = maxVal;
  30.                     }
  31.                 }

  32.                 // 将处理后的图像写入新文件
  33.                 TIFF* out = TIFFOpen(outputFileName, "w");
  34.                 if (out) {
  35.                     TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
  36.                     TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
  37.                     TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 4);
  38.                     TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
  39.                     TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
  40.                     TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  41.                     TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);

  42.                     TIFFWriteEncodedStrip(out, 0, raster, npixels * sizeof(uint32));
  43.                     TIFFClose(out);
  44.                 }
  45.             }
  46.             _TIFFfree(raster);
  47.         }
  48.         TIFFClose(tif);
  49.     } else {
  50.         fprintf(stderr, "Could not open the specified TIFF file\n");
  51.     }
  52. }

  53. int main() {
  54.     processTIFF("input.tif", "output.tif");
  55.     return 0;
  56. }
复制代码


请注意,这是一个基础示例,处理的是32位RGBA TIFF图像。如果你要处理1位或8位的图像,你需要根据具体的TIFF图像格式更改读取和膨胀操作的方式。此外,为了成功编译和运行,你需要在编译时链接libtiff库。

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

使用道具 举报

 楼主| 发表于 2024-11-17 11:48:58 | 显示全部楼层
FishC 发表于 2024-11-17 11:45
如果你想通过现有的方式读取和处理TIF格式的图像,而不依赖OpenCV,可以考虑使用libtiff库。libtiff是 ...

这里面怎样将它修改成2*2的结构元素进行膨胀
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-17 11:49:18 | 显示全部楼层
cxnet 发表于 2024-11-17 11:48
这里面怎样将它修改成2*2的结构元素进行膨胀


要使用2x2的结构元素进行膨胀,你需要遍历每个像素,并检查该像素及其右、下、和右下区域的像素值(因为2x2结构元素在平面上意味着要检查这些位置)。如果其中任一像素有非零值,那么中央像素就设置为最大值。在二值图像的情况下,这意味着任何“1”就使中心值成为“1”。

以下是使用libtiff库的示例代码,假设你已经安装并正确配置了libtiff库:

  1. #include <tiffio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <memory.h>

  6. void processTIFF(const char* inputFileName, const char* outputFileName) {
  7.     TIFF* tif = TIFFOpen(inputFileName, "r");
  8.     if (!tif) {
  9.         printf("Could not open input file %s\n", inputFileName);
  10.         return;
  11.     }

  12.     uint32 width, height;
  13.     size_t nPixels;
  14.     uint32* raster;

  15.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  16.     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  17.     nPixels = width * height;
  18.     raster = (uint32*)_TIFFmalloc(nPixels * sizeof(uint32));

  19.     if (!raster) {
  20.         printf("Memory allocation error\n");
  21.         TIFFClose(tif);
  22.         return;
  23.     }

  24.     // Read image data
  25.     if (!TIFFReadRGBAImage(tif, width, height, raster, 0)) {
  26.         printf("Could not read image\n");
  27.         _TIFFfree(raster);
  28.         TIFFClose(tif);
  29.         return;
  30.     }

  31.     // Creating output raster with the same size
  32.     uint32* outputRaster = (uint32*)_TIFFmalloc(nPixels * sizeof(uint32));
  33.     if (!outputRaster) {
  34.         printf("Memory allocation error\n");
  35.         _TIFFfree(raster);
  36.         TIFFClose(tif);
  37.         return;
  38.     }

  39.     // Copy the original image before processing
  40.     memcpy(outputRaster, raster, nPixels * sizeof(uint32));

  41.     // Dilation with a 2x2 structure
  42.     for (uint32 y = 0; y < height - 1; y++) {
  43.         for (uint32 x = 0; x < width - 1; x++) {
  44.             int isSet = 0;
  45.             uint32 idx = y * width + x;
  46.             
  47.             // Examine 2x2 area
  48.             isSet |= (raster[idx] & 0xFF); // pixel at (x, y)
  49.             isSet |= (raster[idx + 1] & 0xFF); // pixel at (x+1, y)
  50.             isSet |= (raster[idx + width] & 0xFF); // pixel at (x, y+1)
  51.             isSet |= (raster[idx + width + 1] & 0xFF); // pixel at (x+1, y+1)

  52.             if (isSet) {
  53.                 // Set gray-scale to max (assuming 8-bit per channel grayscale)
  54.                 outputRaster[idx] = 0xFFFFFFFF; // white: RGBA all channels max
  55.                 outputRaster[idx + 1] = 0xFFFFFFFF;
  56.                 outputRaster[idx + width] = 0xFFFFFFFF;
  57.                 outputRaster[idx + width + 1] = 0xFFFFFFFF;
  58.             }
  59.         }
  60.     }

  61.     TIFF* out = TIFFOpen(outputFileName, "w");
  62.     if (!out) {
  63.         printf("Could not open output file %s\n", outputFileName);
  64.         _TIFFfree(raster);
  65.         _TIFFfree(outputRaster);
  66.         TIFFClose(tif);
  67.         return;
  68.     }

  69.     TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
  70.     TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
  71.     TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 4);
  72.     TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
  73.     TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
  74.     TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  75.     TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);

  76.     tsize_t lineBytes = 4 * width; // RGBA image
  77.     unsigned char* buf = NULL;   // buffer used to store the horizontal line

  78.     // Allocate buffer for 1 line of span
  79.     buf = (unsigned char*)_TIFFmalloc(lineBytes);
  80.     if (!buf) {
  81.         printf("Memory allocation error\n");
  82.         _TIFFfree(raster);
  83.         _TIFFfree(outputRaster);
  84.         TIFFClose(tif);
  85.         TIFFClose(out);
  86.         return;
  87.     }

  88.     // Write the image
  89.     for (uint32 row = 0; row < height; row++) {
  90.         memcpy(buf, &outputRaster[(height-row-1)*width], lineBytes);   
  91.         if (TIFFWriteScanline(out, buf, row, 0) < 0) {
  92.             break;
  93.         }
  94.     }

  95.     _TIFFfree(buf);
  96.     _TIFFfree(raster);
  97.     _TIFFfree(outputRaster);
  98.     TIFFClose(tif);
  99.     TIFFClose(out);
  100. }

  101. int main() {
  102.     processTIFF("input.tif", "output.tif");
  103.     return 0;
  104. }
复制代码


在这个示例中,遍历图像时,检查当前位置及其上、左、右上方像素的值。若任一位置为1,表示需要设置结果位置为255(即白色)。注意,这段代码是基于假设图像为8位灰度(每像素一个字节),需要根据实际的TIFF格式做调整,比如样本字节大小和像素格式。

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

使用道具 举报

 楼主| 发表于 2024-11-17 11:55:31 | 显示全部楼层
FishC 发表于 2024-11-17 11:49
要使用2x2的结构元素进行膨胀,你需要遍历每个像素,并检查该像素及其右、下、和右下区域的像素值(因 ...

为什么这段代码里的2*2的结构元素膨胀后比opencv的2*2的结构元素所膨胀得要多差不多1像素呢?相当于opencv的3*3的结构元素膨胀效果,我要把它减为1*1结构元素应该修改哪个参数
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-17 11:55:41 | 显示全部楼层
cxnet 发表于 2024-11-17 11:55
为什么这段代码里的2*2的结构元素膨胀后比opencv的2*2 ...


这段代码的膨胀操作实际上是基于2x2邻域(正方形顶部左角开始),它影响的区域是比2x2邻域要多的。这是因为代码遍历了邻近像素并以相对简单的方式扩展了图像。

如果要缩小为1x1结构元素,即简单的自扩展(实际上不扩展任何像素),那么实际上不会改变图像,因为1x1结构元素等同于对像素自身进行检查,没有邻域的影响。所以“1x1膨胀”不会对图像产生变化。

对于只考虑2x2实际的膨胀:

1. 检查每个单独像素而不是树立看整个2x2局部。
2. 确保只有自身参与"扩张",这意味着只修改特定点。

但是,如果你的意思是将不同形状的结果生成,查看代码时注意:

  1. for (int j = 0; j < 2; j++) {
  2.     yy = y + j - 1;
  3.     for (int i = 0; i < 2; i++) {
  4.         xx = x + i - 1;
  5.         if (m_pImage > val) {
  6.             val = m_pImage;
  7.         }
  8.     }
  9. }
复制代码


在上面这个片段中,如果你想控制邻域的大小和形状,调整这两个for循环即可。`1x1`不改变任何邻域,你可以直接输出原始图像而无需额外处理,或者移除所有的`val`赋值步骤,保留`outputRaster`生成部分即可。

如果你遇到了图形扩张结果不是预期问题,可能是邻域处理中访问过多外背景,因此要更谨慎的设置起始和边界条件,如果您需要精细化,使用专业工具(如OpenCV的形态学操作)可能会更合适。但在`libtiff`仅用于读取和原生操作部分,它不提供OpenCV复杂操作。

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

使用道具 举报

 楼主| 发表于 2024-11-17 12:11:24 | 显示全部楼层
FishC 发表于 2024-11-17 11:55
这段代码的膨胀操作实际上是基于2x2邻域(正方形顶部左角开始),它影响的区域是比2x2邻域要多的。这是 ...

用这种方式试了一下大尺寸的TIF图片会出错,看来这种方式也只能处理比较小的图片。

用CImage方式加载TIF二值8位或者1位二值图进行2*2结构元素进行膨胀应该怎样写代码。想试试这种方式是否可行
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-17 12:11:38 | 显示全部楼层
cxnet 发表于 2024-11-17 12:11
用这种方式试了一下大尺寸的TIF图片会出错,看来这种 ...


使用 `CImage` 类来处理 TIFF 图像可以利用 GDI+ 来进行图像加载和处理,从而支持较大的图片。下面是一个使用 `CImage` 和 GDI+ 实现简单膨胀的示例代码:

  1. #include <afxwin.h>     // MFC core and standard components
  2. #include <gdiplus.h>    // GDI+

  3. #pragma comment (lib, "gdiplus.lib")

  4. using namespace Gdiplus;

  5. void ProcessTIFwithCImage(const wchar_t* inputFileName, const wchar_t* outputFileName) {
  6.     // Initialize GDI+
  7.     GdiplusStartupInput gdiplusStartupInput;
  8.     ULONG_PTR gdiplusToken;
  9.     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

  10.     CImage image;
  11.     HRESULT hr = image.Load(inputFileName);
  12.     if (FAILED(hr)) {
  13.         printf("Failed to load image\n");
  14.         return;
  15.     }

  16.     int width = image.GetWidth();
  17.     int height = image.GetHeight();

  18.     // Create a new image for the output
  19.     CImage outputImage;
  20.     outputImage.Create(width, height, 8);

  21.     // Iterate through each pixel, excluding the boundary pixels
  22.     for (int y = 0; y < height - 1; y++) {
  23.         for (int x = 0; x < width - 1; x++) {
  24.             // Check the 2x2 neighborhood for dilation
  25.             BYTE pixelValue = image.GetPixel(x, y) == 0xFFFFFF ? 1 : 0;   // Assuming binary white is the forepixel

  26.             // Check each pixel in 2x2 area
  27.             if (pixelValue == 0) {
  28.                 if ((x + 1 < width && image.GetPixel(x + 1, y) == 0xFFFFFF) ||
  29.                     (y + 1 < height && image.GetPixel(x, y + 1) == 0xFFFFFF) ||
  30.                     (x + 1 < width && y + 1 < height && image.GetPixel(x + 1, y + 1) == 0xFFFFFF)) {
  31.                     pixelValue = 1;
  32.                 }
  33.             }

  34.             // Set the result pixel value
  35.             COLORREF color = pixelValue ? RGB(255, 255, 255) : RGB(0, 0, 0);
  36.             outputImage.SetPixel(x, y, color);
  37.         }
  38.     }

  39.     // Save the processed image to a new file
  40.     outputImage.Save(outputFileName);

  41.     // Cleanup GDI+
  42.     GdiplusShutdown(gdiplusToken);
  43. }

  44. int main() {
  45.     ProcessTIFwithCImage(L"input.tif", L"output.tif");
  46.     return 0;
  47. }
复制代码


### 代码说明:
1. **初始化GDI+**:在使用任何 GDI+ 功能之前,必须进行初始化。

2. **加载图像**:使用 `CImage` 来加载 TIFF 文件。

3. **创建输出图像**:创建一个新的 `CImage` 对象来存储输出结果。

4. **处理图像**:通过遍历图像,为每个非边界像素检查其自身及相邻像素的值,执行膨胀操作。

5. **保存结果**:最后将处理后的图像保存为一个新的 TIFF 文件。

请注意,确保使用 `CImage` 和 GDI+ 方法时,处理二值图像时要保证图像是用正确的格式(比如前景为白色 `0xFFFFFF` 和背景为黑色 `0x000000`)。

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-10 01:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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