鱼C论坛

 找回密码
 立即注册
查看: 1237|回复: 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:45:06 | 显示全部楼层
FishC 发表于 2024-11-17 11:42
要修改代码以处理TIF格式的1位或8位色彩模式的二值图,可以使用OpenCV库来简化操作。主要思路是通过OpenCV ...

排除opencv方法,因为opencv方式打开特别大的图片时很费时间,所以想使用现在这种方式
小甲鱼最新课程 -> 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: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 12:11:24 | 显示全部楼层
FishC 发表于 2024-11-17 11:55
这段代码的膨胀操作实际上是基于2x2邻域(正方形顶部左角开始),它影响的区域是比2x2邻域要多的。这是 ...

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

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-11-5 04:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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