dibsect.cpp
上传用户:lbr_007
上传日期:2019-05-31
资源大小:282k
文件大小:9k
源码类别:

传真(Fax)编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "dibsect.h"
  3. void DIBSection::InitObject(void)
  4. {
  5. m_hbmp = NULL ;
  6. m_pBits = NULL ;
  7. m_pdc = NULL ;
  8. m_total_width = 0;
  9. m_bitcount = 0;
  10. m_size.cx = m_size.cy = m_total_width = 0;
  11. m_geoFlag = false;
  12. }
  13. DIBSection::DIBSection()
  14. {
  15. InitObject();
  16. }
  17. DIBSection::DIBSection(const DIBSection& dib)
  18. {
  19. InitObject();
  20. Copy(dib);
  21. }
  22. DIBSection::~DIBSection()
  23. {
  24. Close();
  25. }
  26. void DIBSection::Copy(const DIBSection& dib)
  27. {
  28. Close();
  29. if (dib.IsCreated())
  30. {
  31. int w = dib.Width();
  32. int h = dib.Height();
  33. int bitcount = dib.GetBitCount();
  34. Create(w,h,bitcount);
  35. if (IsCreated())
  36. {
  37. memcpy(m_pBits,dib.GetConstBits(),(h * m_total_width * bitcount / 8));
  38. }
  39. if (dib.IsGeoImage())
  40. {
  41. SetGeoReference(dib.GetConstGeoReference());
  42. }
  43. }
  44. }
  45. DIBSection& DIBSection::operator = (const DIBSection& dib)
  46. {
  47. Copy(dib);
  48. return *this;
  49. }
  50. void DIBSection::Close(void)
  51. {
  52. if (m_hbmOld)
  53. {
  54. ::SelectObject(m_pdc->GetSafeHdc(), m_hbmOld);
  55. }
  56. if (m_hbmp) DeleteObject(m_hbmp);
  57. if (m_pdc) delete m_pdc;
  58. InitObject();
  59. }
  60. void DIBSection::Create(int cx, int cy, int nbits) 
  61. {
  62. ASSERT(cx > 0);
  63. ASSERT(cy > 0);
  64. ASSERT((nbits == 8) || (nbits == 16) ||
  65.    (nbits == 24) || (nbits == 32)) ;
  66. Close();
  67.  // Save size for drawing later.
  68. m_size.cx = cx ;
  69. m_size.cy = cy ;
  70.  // Initialize the bitmapinfo header
  71. int size = sizeof(BITMAPINFOHEADER) ;
  72. memset(&m_bih, 0, size);
  73.  // Populate bitmapinfo header
  74. m_bih.biSize = size;
  75. m_bih.biWidth = ((((int) cx * 8) + 31) & ~31) >> 3;
  76. m_bih.biHeight = cy;
  77. m_bih.biPlanes = 1;
  78. m_bih.biBitCount = nbits;
  79. m_bih.biCompression = BI_RGB;
  80. m_total_width = m_bih.biWidth;
  81. m_bitcount = nbits;
  82.   // Create a new DC.
  83. m_pdc = new CDC ;
  84. m_pdc->CreateCompatibleDC(NULL);
  85.   // Create the DIB section.
  86. m_hbmp = CreateDIBSection( m_pdc->GetSafeHdc(),
  87. (BITMAPINFO*)&m_bih,
  88. DIB_RGB_COLORS,
  89. &m_pBits,
  90. NULL,
  91. 0);
  92. ASSERT(m_hbmp);
  93. ASSERT(m_pBits);
  94.   // Select the bitmap into the buffer
  95. if (m_hbmp)
  96. {
  97. m_hbmOld = (HBITMAP)::SelectObject(m_pdc->GetSafeHdc(),
  98.    m_hbmp);
  99. }
  100. void DIBSection::Draw(CDC* pdcDest, int x, int y) 
  101. {
  102. pdcDest->BitBlt( 0, 0,
  103.  m_size.cx, m_size.cy,
  104.  m_pdc,
  105.  x, y,
  106.  SRCCOPY);
  107. }
  108. void DIBSection::SetPixel(UINT32 x, UINT32 y, COLORREF cr)
  109. {
  110. if ((x < Width()) && (y < Height()))
  111. {
  112. unsigned char * bits = (unsigned char *)GetBits();
  113. UINT32 offset = x * GetBitCount()/8 + (Height() - y - 1)*GetTotalWidth()*GetBitCount()/8;
  114. bits[offset++] = GetBValue(cr);
  115. bits[offset++] = GetGValue(cr);
  116. bits[offset] = GetRValue(cr);
  117. }
  118. }
  119. void DIBSection::GetPixel(UINT32 x, UINT32 y, COLORREF& cr)
  120. {
  121. if ((x < Width()) && (y < Height()))
  122. {
  123. unsigned char * src = (unsigned char *)GetBits();
  124. unsigned char * dst = (unsigned char *)&cr;
  125. UINT32 offset = x * GetBitCount()/8 + (Height() - y - 1)*GetTotalWidth()*GetBitCount()/8;
  126. dst[3] = 0;
  127. dst[2] = src[offset++];
  128. dst[1] = src[offset++];
  129. dst[0] = src[offset];
  130. }
  131. }
  132. void DIBSection::ResizeImage(DIBSection& dst_dib, int w, int h)
  133. {
  134. if ((w > 0) && (h > 0))
  135. {
  136. dst_dib.Create(w,h,GetBitCount());
  137. if (dst_dib.IsCreated())
  138. {
  139. UINT32 width = dst_dib.Width();
  140. UINT32 height = dst_dib.Height();
  141. UINT32 src_width = Width();
  142. UINT32 src_height = Height();
  143. if ((dst_dib.IsCreated() && (width > 0) && (height > 0)) &&
  144. (IsCreated() && (src_width > 0) && (src_height > 0)))
  145. {
  146. double horizontal_scale = (double)src_width/(double)dst_dib.Width();
  147. double vertical_scale = (double)src_height/(double)dst_dib.Height();
  148. unsigned char * src_ptr = (unsigned char *)GetBits();
  149. unsigned char * dst_ptr = (unsigned char *)dst_dib.GetBits();
  150. UINT32 src_bytecount = GetBitCount()/8;
  151. UINT32 src_dibwidth = GetTotalWidth();
  152. UINT32 dst_bytecount = dst_dib.GetBitCount()/8;
  153. UINT32 dst_dibwidth = dst_dib.GetTotalWidth();
  154. UINT32 dst_bitcount = dst_dib.GetBitCount();
  155. UINT32 src_row, src_col;
  156. UINT32 src_index, dst_index;
  157. for (UINT32 row=0;row<height;row++){
  158. src_row = (UINT32)(row * vertical_scale + 0.50);
  159. if (src_row >= src_height) src_row = src_height - 1;
  160. for (UINT32 col=0;col<width;col++){
  161. src_col = (UINT32)(col * horizontal_scale + 0.50);
  162. if (src_col >= src_width) src_col = src_width-1;
  163. src_index = src_row * src_dibwidth * src_bytecount + src_col*src_bytecount;
  164. dst_index = row*dst_dibwidth*dst_bytecount+col*dst_bytecount;
  165. memcpy(&dst_ptr[dst_index],
  166. &src_ptr[src_index],
  167. dst_bytecount);
  168. }
  169. }
  170. }
  171. }
  172. }
  173. }
  174. void DIBSection::PatBlt(DWORD pattern)
  175. {
  176. if (IsCreated())
  177. {
  178. if ((Width() > 0) && (Height() > 0))
  179. {
  180. m_pdc->PatBlt(0,0,Width(),Height(),pattern);
  181. }
  182. }
  183. }
  184. void DIBSection::HistogramEqualization(DIBSection& dib)
  185. {
  186. INT32 x, y, i, j, sum;
  187. INT32 dr, dg, db, delta;
  188. INT32 ihist[256];
  189. float fsum;
  190. float hist[256];
  191. INT32 histeq[256];
  192. INT32 w = dib.Width();
  193. INT32 h = dib.Height();
  194. INT32 bitcount = dib.GetBitCount();
  195. INT32 bytespp = bitcount / 8; // bytes per pixel
  196. INT32 width = w * bytespp;
  197. memset(ihist,0,(size_t)(sizeof(int)*256));
  198. unsigned char * img_ptr = (unsigned char *)dib.GetBits();
  199. unsigned char * intensity = new unsigned char[(w * h)];
  200. UINT32 row, column;
  201. UINT32 r, g, b;
  202. INT32 index, image_index;
  203.   // first pass is for calculating the intensity of each pixel
  204.   // for this pass image_index is used for original image, and index
  205.   // is used for intensity image
  206. for (row=0;row<h;row++){
  207. for (column=0;column<w;column++){
  208. index = row * w + column;
  209. image_index = row * width + column*bytespp;
  210. r = (UINT32)img_ptr[image_index];
  211. g = (UINT32)img_ptr[++image_index];
  212. b = (UINT32)img_ptr[++image_index];
  213. i = (UINT32)(0.50 + (r + g + b)/3.0);
  214. if (i>255) i = 255;
  215. intensity[index] = (unsigned char)i;
  216. }
  217. }
  218. sum = 0;
  219. for (y=0;y<h;y++){
  220. for (x=0;x<w;x++){
  221. j = intensity[x + y*w];
  222. ihist[j] += 1;
  223. sum++;
  224. }
  225. }
  226. for (i=0;i<256;i++){
  227. hist[i] = (float)ihist[i] / (float)sum;
  228. }
  229. for (i=0;i<256;i++){
  230. fsum = 0.0f;
  231. for (j=0;j<=i;j++){
  232. fsum += hist[j];
  233. }
  234. histeq[i] = (INT32)(fsum*255.0f + 0.50f);
  235. }
  236. for (row=0;row<h;row++){
  237. for (column=0;column<w;column++){
  238. index = row * w + column;
  239. image_index = row * width + column*bytespp;
  240. //image_index += add_one;
  241. delta = histeq[intensity[index]] - intensity[index];
  242. dr = (UINT32)img_ptr[image_index] + delta;
  243. dg = (UINT32)img_ptr[image_index+1] + delta;
  244. db = (UINT32)img_ptr[image_index+2] + delta;
  245. if (dr < 0) dr = 0;
  246. if (dr > 255) dr = 255;
  247. if (dg < 0) dg = 0;
  248. if (dg > 255) dg = 255;
  249. if (db < 0) db = 0;
  250. if (db > 255) db = 255;
  251. img_ptr[image_index] = (unsigned char)dr;
  252. img_ptr[++image_index] = (unsigned char)dg;
  253. img_ptr[++image_index] = (unsigned char)db;
  254. }
  255. }
  256. delete [] intensity;
  257. //delete [] intensity_copy;
  258. }
  259. void DIBSection::Greyscale(DIBSection& dib)
  260. {
  261. INT32 i;
  262. INT32 w = dib.Width();
  263. INT32 h = dib.Height();
  264. INT32 bitcount = dib.GetBitCount();
  265. INT32 bytespp = bitcount / 8; // bytes per pixel
  266. INT32 width = w * bytespp;
  267. unsigned char * img_ptr = (unsigned char *)dib.GetBits();
  268. UINT32 row, column;
  269. UINT32 r, g, b;
  270. //INT32 val, i1, i2;
  271. INT32 image_index;
  272.   // first pass is for calculating the intensity of each pixel
  273.   // for this pass image_index is used for original image, and index
  274.   // is used for intensity image
  275. for (row=0;row<h;row++){
  276. for (column=0;column<w;column++){
  277. image_index = row * width + column*bytespp;
  278. r = (UINT32)img_ptr[image_index];
  279. g = (UINT32)img_ptr[image_index+1];
  280. b = (UINT32)img_ptr[image_index+2];
  281. i = (UINT32)(0.50 + (r + g + b)/3.0);
  282. if (i>255) i = 255;
  283. memset(&img_ptr[image_index],i,3);
  284. }
  285. }
  286. }
  287. void DIBSection::Lighten(INT32 amt)
  288. {
  289. INT32 w = Width();
  290. INT32 h = Height();
  291. INT32 bitcount = GetBitCount();
  292. INT32 bytespp = bitcount / 8; // bytes per pixel
  293. INT32 width = w * bytespp;
  294. unsigned char * img_ptr = (unsigned char *)GetBits();
  295. UINT32 row, column;
  296. INT32 r, g, b;
  297. INT32 image_index;
  298.   // first pass is for calculating the intensity of each pixel
  299.   // for this pass image_index is used for original image, and index
  300.   // is used for intensity image
  301. for (row=0;row<h;row++){
  302. for (column=0;column<w;column++){
  303. image_index = row * width + column*bytespp;
  304. r = (INT32)img_ptr[image_index];
  305. g = (INT32)img_ptr[image_index+1];
  306. b = (INT32)img_ptr[image_index+2];
  307. r += amt;
  308. g += amt;
  309. b += amt;
  310. r = (r > 0) ? ((r<256)?r:255) : 0;
  311. g = (g > 0) ? ((g<256)?g:255) : 0;
  312. b = (b > 0) ? ((b<256)?b:255) : 0;
  313. img_ptr[image_index] = (unsigned char)r;
  314. img_ptr[image_index+1] = (unsigned char)g;
  315. img_ptr[image_index+2] = (unsigned char)b;
  316. }
  317. }
  318. }