Dib.cpp
上传用户:ynjin1970
上传日期:2014-10-13
资源大小:6438k
文件大小:9k
源码类别:

中间件编程

开发平台:

Visual C++

  1. // Dib.cpp: implementation of the CDib class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "Cloud.h"
  6. #include "Dib.h"
  7. #include "math.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. #define PI  3.14159265358979
  14. //////////////////////////////////////////////////////////////////////
  15. // Construction/Destruction
  16. //////////////////////////////////////////////////////////////////////
  17. CDib::CDib()
  18. {
  19. m_Height=0;
  20. m_Width=0;
  21. hDIB=NULL;
  22. bmInfoHeader=NULL;
  23. bmpInfo =NULL;
  24. lpDIBBits=NULL;
  25. }
  26. CDib::~CDib()
  27. {
  28. ClearMemory();
  29. }
  30. /////////////////////////////////////////////////////////////////////////
  31. //打开并读取图像文件
  32. void CDib::ReadDIBFile(LPTSTR lpFilename)
  33. {
  34. BITMAPFILEHEADER bmfHeader;//图像文件头
  35. CFile File;
  36. CFileException Err;
  37. if(!File.Open(lpFilename,CFile::modeRead|CFile::shareDenyNone,&Err))
  38. {
  39. AfxMessageBox(Err.m_cause);
  40. return;
  41. }
  42. File.Read(&bmfHeader,sizeof(bmfHeader));
  43. if(bmfHeader.bfType!=0x4d42)
  44. {
  45. AfxMessageBox("此文件不是位图文件");
  46. return;
  47. }
  48. DWORD Filelen=File.GetLength();
  49. if(bmfHeader.bfSize!=Filelen)
  50. {
  51. AfxMessageBox("该文件已经损坏!");
  52. return;
  53. }
  54. hDIB=NULL;
  55. hDIB=new BYTE[Filelen-sizeof(BITMAPFILEHEADER)];
  56. if(!hDIB)
  57. {
  58. AfxMessageBox("内存不够!");
  59. return;
  60. }
  61. File.Read(hDIB,Filelen-sizeof(BITMAPFILEHEADER));
  62. File.Close();
  63. }
  64. /////////////////////////////////////////////////////////////////////////
  65. //装载DIB
  66. void CDib::LoadDIB(LPTSTR lpFilename)
  67. {
  68. ReadDIBFile(lpFilename);
  69. bmInfoHeader=(LPBITMAPINFOHEADER)hDIB;
  70. bmpInfo=(LPBITMAPINFO)hDIB;
  71. int ColorsNum=GetDIBColorsNum(bmInfoHeader);
  72. lpDIBBits=(BYTE*)hDIB+ColorsNum*sizeof(RGBQUAD)+sizeof(BITMAPINFOHEADER);
  73. m_Height=bmInfoHeader->biHeight;
  74. m_Width=bmInfoHeader->biWidth;
  75. }
  76. long CDib::GetImageHeight()
  77. {
  78. return m_Height;
  79. }
  80. long CDib::GetImageWidth()
  81. {
  82. return m_Width;
  83. }
  84. /////////////////////////////////////////////////////////////////////////
  85. //从得到图像颜色数
  86. int CDib::GetDIBColorsNum(BITMAPINFOHEADER* bmInfoHeader)
  87. {
  88. int ColorsNum;//图像颜色数
  89. switch(bmInfoHeader->biBitCount)
  90. {
  91. case 1:
  92. ColorsNum=2;
  93. break;
  94. case 4:
  95. ColorsNum=16;
  96. break;
  97. case 8:
  98. ColorsNum=256;
  99. break;
  100. default:
  101. ColorsNum=0;
  102. break;
  103. }
  104. return ColorsNum;
  105. }
  106. /////////////////////////////////////////////////////////////////////////
  107. //把DIB选入到指定设备hDC
  108. BOOL CDib::PaintDIB(HDC hDC,long width,long height)
  109. {
  110. int bSuccess;
  111. HPALETTE hPal=NULL;
  112. HPALETTE hOldPal;
  113. if(!hDIB)
  114. return FALSE;
  115. if(!hPal)
  116. CreateDIBPalette();
  117. if(hPal)
  118. {
  119. hOldPal=SelectPalette(hDC,hPal,TRUE);
  120. RealizePalette(hDC);
  121. }
  122. SetStretchBltMode(hDC,COLORONCOLOR);
  123. bSuccess=StretchDIBits(hDC,0,0,width,
  124.                    height,0,0,m_Width,m_Height,lpDIBBits, 
  125.                        bmpInfo,DIB_RGB_COLORS,SRCCOPY);
  126. if(hOldPal)
  127. SelectPalette(hDC,hOldPal,FALSE);
  128. return bSuccess;
  129. }
  130. /////////////////////////////////////////////////////////////////////////
  131. //生成自己的调色板
  132. HPALETTE CDib::CreateDIBPalette()
  133. {
  134. LOGPALETTE* lpPal;
  135. HPALETTE hPal=NULL;
  136. int wNumColors=GetDIBColorsNum(bmInfoHeader);
  137. lpPal=(LOGPALETTE*)new BYTE[wNumColors*sizeof(PALETTEENTRY)+2*sizeof(WORD)];
  138. lpPal->palNumEntries=wNumColors;
  139. lpPal->palVersion=1;
  140. for(int i=0;i<wNumColors;i++)
  141. {
  142.      lpPal->palPalEntry[i].peBlue=bmpInfo->bmiColors[i].rgbBlue;
  143.      lpPal->palPalEntry[i].peGreen=bmpInfo->bmiColors[i].rgbGreen;
  144.      lpPal->palPalEntry[i].peRed=bmpInfo->bmiColors[i].rgbRed;
  145.      lpPal->palPalEntry[i].peFlags=bmpInfo->bmiColors[i].rgbReserved=(BYTE)0;
  146. }
  147. hPal=CreatePalette(lpPal);
  148. return hPal;
  149. }
  150. /////////////////////////////////////////////////////////////////////////
  151. //释放内存
  152. void CDib::ClearMemory()
  153. {
  154. delete[] hDIB;
  155. delete[] bmInfoHeader;
  156. delete[] bmpInfo;
  157. delete[] lpDIBBits;
  158. }
  159. /////////////////////////////////////////////////////////////////////////
  160. //获得DIB数据指针
  161. HANDLE CDib::GetDIBHandle()
  162. {
  163. return hDIB;
  164. }
  165. /////////////////////////////////////////////////////////////////////////
  166. //从DIB获得DDB
  167. //////////////////////////////////////////
  168. //////////图像灰度线性变换函数
  169. BOOL CDib::OnChangeBrightness(float fa,float fb)
  170. {
  171. if(!lpDIBBits)
  172. {
  173. AfxMessageBox("请先打开图像");
  174. return FALSE;
  175. }
  176. BYTE* temDIBits;
  177. if(bmInfoHeader->biBitCount!=24)
  178. {
  179. AfxMessageBox("只能对24位真彩色的图像进行变换");
  180. return FALSE;
  181. }
  182. int w=m_Width;
  183. int h=m_Height;
  184. int sign=w%2;
  185. long total=w*h*3;
  186. long k=0;
  187. if(sign)
  188. w+=1;
  189. temDIBits=new BYTE[total];
  190. memcpy(temDIBits,lpDIBBits,total);
  191. for(int i=0;i<h;i++)
  192. {
  193. for(int j=0;j<w;j++)
  194. {
  195. float fTem;
  196. fTem=fa*temDIBits[k]+fb;//红色通道
  197. if(fTem>255)
  198. {
  199. lpDIBBits[k]=(BYTE)255;
  200. }else
  201. if(fTem<0)
  202. {
  203. lpDIBBits[k]=(BYTE)0;
  204. }else
  205. {
  206. lpDIBBits[k]=(BYTE)(fTem+0.5);
  207. }
  208. fTem=fa*temDIBits[k+1]+fb;//绿色通道
  209. if(fTem>255)
  210. {
  211. lpDIBBits[k+1]=(BYTE)255;
  212. }else
  213. if(fTem<0)
  214. {
  215. lpDIBBits[k+1]=(BYTE)0;
  216. }else
  217. {
  218. lpDIBBits[k+1]=(BYTE)(fTem+0.5);
  219. }
  220. fTem=fa*temDIBits[k+2]+fb;//蓝色通道
  221. if(fTem>255)
  222. {
  223. lpDIBBits[k+2]=(BYTE)255;
  224. }else
  225. if(fTem<0)
  226. {
  227. lpDIBBits[k+2]=(BYTE)0;
  228. }else
  229. {
  230. lpDIBBits[k+2]=(BYTE)(fTem+0.5);
  231. }
  232. if(k>=total)
  233. break;
  234. k+=3;
  235. }
  236. }
  237. return TRUE;
  238. }
  239. /////////////////////////////////////////////////////////////////
  240. //////////////////灰度拉伸函数
  241. BOOL CDib::OnGrayStretch(BYTE x1,BYTE x2,BYTE y1,BYTE y2)
  242. {
  243. if(!lpDIBBits)
  244. {
  245. AfxMessageBox("请先打开图像");
  246. return FALSE;
  247. }
  248. if(bmInfoHeader->biBitCount!=24)
  249. {
  250. AfxMessageBox("只能对24位真彩色的图像进行变换");
  251. return FALSE;
  252. }
  253. int w=m_Width;
  254. int h=m_Height;
  255. int sign=w%2;
  256. long total=w*h*3;
  257. long k=0;
  258. if(sign)
  259. w+=1;
  260. BYTE A=(y2-y1)/(x2-x1);
  261. for(int i=0;i<h;i++)
  262. {
  263. for(int j=0;j<w;j++)
  264. {
  265. float fTem;
  266. if(lpDIBBits[k]>=x1&&lpDIBBits[k]<=x2)
  267. {
  268. fTem=lpDIBBits[k];
  269. lpDIBBits[k]=(BYTE)fTem*A+y1;
  270. lpDIBBits[k+1]=(BYTE)fTem*A+y1;
  271. lpDIBBits[k+2]=(BYTE)fTem*A+y1;
  272. }else if(lpDIBBits[k]<x1)
  273. {
  274. lpDIBBits[k]=y1;
  275. lpDIBBits[k+1]=y1;
  276. lpDIBBits[k+2]=y1;
  277. }else
  278. {
  279. lpDIBBits[k]=y2;
  280. lpDIBBits[k+1]=y2;
  281. lpDIBBits[k+2]=y2;
  282. }
  283. if(k>=total)
  284. break;
  285. k+=3;
  286. }
  287. }
  288. return TRUE;
  289. }
  290. /////////////////////////////////////////////////////////////////
  291. //////////////////灰度化图像函数
  292. BOOL CDib::OnChangeToGray()
  293. {
  294. if(!lpDIBBits)
  295. {
  296. AfxMessageBox("请先打开图像");
  297. return FALSE;
  298. }
  299. if(bmInfoHeader->biBitCount!=24)
  300. {
  301. AfxMessageBox("只能对24位真彩色的图像进行变换");
  302. return FALSE;
  303. }
  304. int w=m_Width;
  305. int h=m_Height;
  306. int sign=w%2;
  307. long total=w*h*3;
  308. long k=0;
  309. if(sign)
  310. w+=1;
  311. for(int i=0;i<h;i++)
  312. {
  313. for(int j=0;j<w;j++)
  314. {
  315. float fTem;
  316. fTem=(float)(lpDIBBits[k]+lpDIBBits[k+1]+lpDIBBits[k+2])/3;//灰度值为三色RGB的平均值
  317. lpDIBBits[k]=(BYTE)fTem;
  318. lpDIBBits[k+1]=(BYTE)fTem;
  319. lpDIBBits[k+2]=(BYTE)fTem;
  320. if(k>=total)
  321. break;
  322. k+=3;
  323. }
  324. }
  325. return TRUE;
  326. }
  327. ////////////////////////////////////////////////////////
  328. //直方图均衡化函数
  329. void CDib::OnHistogramEqualize()
  330. {
  331. if(!lpDIBBits)
  332. {
  333. AfxMessageBox("请先打开图像");
  334. return;
  335. }
  336. if(bmInfoHeader->biBitCount!=24)
  337. {
  338. AfxMessageBox("只能对24位真彩色的图像进行变换");
  339. return;
  340. }
  341. OnChangeToGray();//灰度化图像
  342. int w=m_Width;
  343. int h=m_Height;
  344. int sign=w%2;
  345. long total=w*h*3;
  346. long k=0;//像素lpBITBits的下标
  347. long Temp;
  348. BYTE bMap[256];//新的灰度表
  349. long iCount[256];//图像0-255每种灰度的点数
  350. for(int i=0;i<256;i++)
  351. {
  352. iCount[i]=0;
  353. }
  354. if(sign)
  355. w+=1;
  356. for(i=0;i<h;i++)//统计每一级灰度的点的数量
  357. {
  358. for(int j=0;j<w;j++)
  359. {
  360. iCount[lpDIBBits[k]]++;
  361. if(k>=total)
  362. break;
  363. k+=3;
  364. }
  365. }
  366. for(i=0;i<256;i++)//计算新的灰度表
  367. {
  368. Temp=0;
  369. for(int j=0;j<i;j++)
  370. {
  371. Temp+=iCount[j];
  372. }
  373. bMap[i]=(BYTE)(Temp*255/h/w);
  374. }
  375. k=0;
  376. for(i=0;i<h;i++)//给每个像素点付新值
  377. {
  378. for(int j=0;j<w;j++)
  379. {
  380. BYTE tem=lpDIBBits[k];
  381. lpDIBBits[k]=bMap[tem];
  382. lpDIBBits[k+1]=bMap[tem];
  383. lpDIBBits[k+2]=bMap[tem];
  384. if(k>=total)
  385. break;
  386. k+=3;
  387. }
  388. }
  389. }
  390. ////////////////////////////////////////////////////////////////////////
  391. ///傅里叶变换In输入,其长度是图像占有字节数的两倍,i=偶数为实部,
  392. //i=奇数为虚部;nn是一个数组代表图像的宽度和高度,
  393. //sign为1或-1,分别表示正、负傅里叶变换