ImageEx.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. #include "StdAfx.h"
  2. #include "ImageEx.h"
  3. #include <math.h>
  4. //////////////////////////////////////////////////////////////////////////////////
  5. //构造函数
  6. CImageEx::CImageEx()
  7. {
  8. ::SetRect(&m_rcNinePart,0,0,0,0);
  9. m_cbAlpha = 255;
  10. return;
  11. }
  12. //析构函数
  13. CImageEx::~CImageEx()
  14. {
  15. //销毁图片
  16. DestroyImage();
  17. return;
  18. }
  19. //销毁图片
  20. bool CImageEx::DestroyImage()
  21. {
  22. Destroy();
  23. return true;
  24. }
  25. //加载图片
  26. bool CImageEx::LoadImage(LPCTSTR pszFileName)
  27. {
  28. HRESULT hr = CImage::Load(pszFileName);
  29. if (hr == S_OK)
  30. {
  31. return SetAlphaBit();
  32. }
  33. else
  34. {
  35. return FALSE;
  36. }
  37. }
  38. //加载图片
  39. bool CImageEx::LoadImage(HINSTANCE hInstance, LPCTSTR pszResourceName,LPCTSTR pszResourceType/*=TEXT("IMAGE")*/)
  40. {
  41. //查找资源
  42. HRSRC hResource=FindResource(hInstance,pszResourceName,pszResourceType);
  43. if (hResource==NULL) return false;
  44. //读取资源
  45. DWORD dwImageSize=SizeofResource(hInstance,hResource);
  46. LPVOID pImageBuffer=LoadResource(hInstance,hResource);
  47. //创建数据
  48. IStream * pIStream=NULL;
  49. if (CreateStreamOnHGlobal(NULL,TRUE,&pIStream)!=S_OK)
  50. {
  51. ASSERT(FALSE);
  52. return false;
  53. }
  54. //写入数据
  55. pIStream->Write(pImageBuffer,dwImageSize,NULL);
  56. HRESULT hr = CImage::Load(pIStream);
  57. //释放资源
  58. SafeRelease(pIStream);
  59. if (hr == S_OK)
  60. {
  61. return SetAlphaBit();
  62. }
  63. else
  64. {
  65. return FALSE;
  66. }
  67. }
  68. //绘画图像
  69. BOOL CImageEx::DrawImage(CDC * pDC, INT nXPos, INT nYPos)
  70. {
  71. pDC->SetStretchBltMode(HALFTONE);
  72. if ( m_ImageClone.IsNull() )
  73. return CImage::Draw(pDC->GetSafeHdc(),nXPos,nYPos,GetWidth(),GetHeight());
  74. else
  75. {
  76. if ( m_cbAlpha != 255 )
  77. m_ImageClone.AlphaBlend(pDC->GetSafeHdc(),nXPos,nYPos,GetWidth(),GetHeight(),0,0,GetWidth(),GetHeight(),m_cbAlpha);
  78. else m_ImageClone.Draw(pDC->GetSafeHdc(),nXPos,nYPos,GetWidth(),GetHeight());
  79. }
  80. return CImage::Draw(pDC->GetSafeHdc(),nXPos,nYPos);
  81. }
  82. //绘画图像
  83. BOOL CImageEx::DrawImage( CDC * pDC, INT nXPos, INT nYPos, INT nDestWidth, INT nDestHeight )
  84. {
  85. pDC->SetStretchBltMode(HALFTONE);
  86. if( nDestWidth == 0 || nDestHeight == 0 ) return FALSE;
  87. if ( m_ImageClone.IsNull() )
  88. return CImage::Draw(pDC->GetSafeHdc(),nXPos,nYPos,nDestWidth,nDestHeight);
  89. else
  90. {
  91. if ( m_cbAlpha != 255 )
  92. m_ImageClone.AlphaBlend(pDC->GetSafeHdc(),nXPos,nYPos,nDestWidth,nDestHeight,0,0,GetWidth(),GetHeight(),m_cbAlpha);
  93. else m_ImageClone.Draw(pDC->GetSafeHdc(),nXPos,nYPos,nDestWidth,nDestHeight);
  94. }
  95. return FALSE;
  96. }
  97. //绘画图像
  98. BOOL CImageEx::DrawImage( CDC * pDC, RECT &rc )
  99. {
  100. pDC->SetStretchBltMode(HALFTONE);
  101. if( rc.right-rc.left == 0 || rc.bottom-rc.top == 0 ) return FALSE;
  102. if ( m_ImageClone.IsNull() )
  103. return CImage::Draw(pDC->GetSafeHdc(),rc);
  104. else
  105. {
  106. if ( m_cbAlpha != 255 )
  107. m_ImageClone.AlphaBlend(pDC->GetSafeHdc(),rc,CRect(0,0,m_ImageClone.GetWidth(),m_ImageClone.GetHeight()),m_cbAlpha);
  108. else
  109. {
  110. if ( m_cbAlpha != 255 )
  111. m_ImageClone.AlphaBlend(pDC->GetSafeHdc(),rc.left,rc.top,(rc.right-rc.left),(rc.bottom-rc.top),0,0,GetWidth(),GetHeight(),m_cbAlpha);
  112. else m_ImageClone.Draw(pDC->GetSafeHdc(),rc);
  113. }
  114. }
  115. return FALSE;
  116. }
  117. //绘画图像
  118. BOOL CImageEx::DrawImage(CDC * pDC, INT nXDest, INT nYDest, INT nDestWidth, INT nDestHeight, INT nXScr, INT nYSrc)
  119. {
  120. pDC->SetStretchBltMode(HALFTONE);
  121. if( nDestWidth == 0 || nDestHeight == 0 ) return FALSE;
  122. if ( m_ImageClone.IsNull() )
  123. return CImage::Draw(pDC->GetSafeHdc(),nXDest,nYDest,nDestWidth,nDestHeight,nXScr,nYSrc,GetWidth(),GetHeight());
  124. else
  125. {
  126. if ( m_cbAlpha != 255 )
  127. m_ImageClone.AlphaBlend(pDC->GetSafeHdc(),nXDest,nYDest,nDestWidth,nDestHeight,nXScr,nYSrc,GetWidth(),GetHeight(),m_cbAlpha);
  128. else m_ImageClone.Draw(pDC->GetSafeHdc(),nXDest,nYDest,nDestWidth,nDestHeight,nXScr,nYSrc,GetWidth(),GetHeight());
  129. }
  130. return FALSE;
  131. }
  132. //绘画图像
  133. BOOL CImageEx::DrawImage(CDC * pDC, INT nXDest, INT nYDest, INT nDestWidth, INT nDestHeight, INT nXScr, INT nYSrc, INT nSrcWidth, INT nSrcHeight)
  134. {
  135. pDC->SetStretchBltMode(HALFTONE);
  136. if( nSrcWidth == 0 || nSrcHeight == 0 ) return FALSE;
  137. if ( m_ImageClone.IsNull() )
  138. return CImage::Draw(pDC->GetSafeHdc(),nXDest,nYDest,nDestWidth,nDestHeight,nXScr,nYSrc,nSrcWidth,nSrcHeight);
  139. else
  140. {
  141. if ( m_cbAlpha != 255 )
  142. m_ImageClone.AlphaBlend(pDC->GetSafeHdc(),nXDest,nYDest,nDestWidth,nDestHeight,nXScr,nYSrc,nDestWidth,nDestHeight,m_cbAlpha);
  143. else m_ImageClone.Draw(pDC->GetSafeHdc(),nXDest,nYDest,nDestWidth,nDestHeight,nXScr,nYSrc,nSrcWidth,nSrcHeight);
  144. }
  145. return FALSE;
  146. }
  147. bool CImageEx::Draw( CDC * pDC, INT x, INT y, INT cx, INT cy,INT nLeft,INT nTop,INT nRight,INT nBottom )
  148. {
  149. int cxImage = GetWidth();
  150. int cyImage = GetHeight();
  151. // 左上
  152. {
  153. RECT rcDest = {x, y, x+nLeft, y+nTop};
  154. RECT rcSrc = {0, 0, nLeft, nTop};
  155. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  156. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  157. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  158. }
  159. // 左边
  160. {
  161. RECT rcDest = {x, y+nTop, x+nLeft, (y+nTop)+(cy-nTop-nBottom)};
  162. RECT rcSrc = {0, nTop, nLeft, nTop+(cyImage-nTop-nBottom)};
  163. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  164. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  165. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  166. }
  167. // 上边
  168. {
  169. RECT rcDest = {x+nLeft, y,x+(cx-nRight), y+nTop};
  170. RECT rcSrc = {nLeft, 0, (cxImage-nLeft-nRight), nTop};
  171. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  172. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  173. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  174. }
  175. // 右上
  176. {
  177. RECT rcDest = {x+(cx-nRight), y, (x+(cx-nRight))+nRight, y+nTop};
  178. RECT rcSrc = {cxImage-nRight, 0, (cxImage-nRight)+nRight, nTop};
  179. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  180. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  181. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  182. }
  183. // 右边
  184. {
  185. RECT rcDest = {x+(cx-nRight), y+nTop, (x+(cx-nRight))+nRight, (y+nTop)+(cy-nTop-nBottom)};
  186. RECT rcSrc = {cxImage-nRight, nTop, (cxImage-nRight)+nRight, nTop+(cyImage-nTop-nBottom)};
  187. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  188. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  189. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  190. }
  191. // 下边
  192. {
  193. RECT rcDest = {x+nLeft, y+(cy-nBottom), (x+nLeft)+(cx-nLeft-nRight), (y+(cy-nBottom))+nBottom};
  194. RECT rcSrc = {nLeft, cyImage-nBottom, nLeft+(cxImage-nLeft-nRight), (cyImage-nBottom)+nBottom};
  195. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  196. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  197. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  198. }
  199. // 右下
  200. {
  201. RECT rcDest = {x+(cx-nRight), y+(cy-nBottom), (x+(cx-nRight))+nRight, (y+(cy-nBottom))+nBottom};
  202. RECT rcSrc = {cxImage-nRight, cyImage-nBottom, (cxImage-nRight)+nRight, (cyImage-nBottom)+nBottom};
  203. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  204. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  205. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  206. }
  207. // 左下
  208. {
  209. RECT rcDest = {x, y+(cy-nBottom), x+nLeft, (y+(cy-nBottom))+nBottom};
  210. RECT rcSrc = {0, cyImage-nBottom, nLeft, (cyImage-nBottom)+nBottom};
  211. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  212. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  213. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  214. }
  215. // 中间
  216. {
  217. RECT rcDest = {x+nLeft, y+nTop, x+(cx-nRight), y+(cy-nBottom)};
  218. RECT rcSrc = {nLeft, nTop, cxImage-nRight, cyImage-nBottom};
  219. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  220. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  221. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  222. }
  223. return true;
  224. }
  225. bool CImageEx::Draw( CDC * pDC, const RECT& rectDest, const RECT& rectSrc )
  226. {
  227. return Draw(pDC,rectDest.left, rectDest.top, rectDest.right-rectDest.left, rectDest.bottom-rectDest.top,
  228. rectSrc.left, rectSrc.top,rectSrc.right, rectSrc.bottom);
  229. }
  230. bool CImageEx::Draw( CDC * pDC, const RECT& rectDest )
  231. {
  232. return Draw(pDC,rectDest,m_rcNinePart);
  233. }
  234. bool CImageEx::DrawFrame( CDC * pDC, const RECT& rectDest )
  235. {
  236. INT x = rectDest.left;
  237. INT y = rectDest.top;
  238. INT cx = rectDest.right-rectDest.left;
  239. INT cy = rectDest.bottom - rectDest.top;
  240. INT nLeft = m_rcNinePart.left;
  241. INT nTop = m_rcNinePart.top;
  242. INT nRight = m_rcNinePart.right;
  243. INT nBottom = m_rcNinePart.bottom;
  244. // 左边
  245. {
  246. RECT rcDest = {x, y, x+nLeft, (y+nTop)+(cy)};
  247. RECT rcSrc = {0, nTop, nLeft, nTop+(GetHeight()-nTop-nBottom)};
  248. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  249. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  250. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  251. }
  252. // 上边
  253. {
  254. RECT rcDest = {x, y,x+(cx), y+nTop};
  255. RECT rcSrc = {nLeft, 0, (GetWidth()-nLeft-nRight), nTop};
  256. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  257. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  258. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  259. }
  260. // 右边
  261. {
  262. RECT rcDest = {x+(cx-nRight), y+nTop, (x+(cx-nRight))+nRight, (y+nTop)+(cy-nTop-nBottom)};
  263. RECT rcSrc = {GetWidth()-nRight, nTop, (GetWidth()-nRight)+nRight, nTop+(GetHeight()-nTop-nBottom)};
  264. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  265. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  266. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  267. }
  268. // 下边
  269. {
  270. RECT rcDest = {x, y+(cy-nBottom), (x)+(cx), (y+(cy-nBottom))+nBottom};
  271. RECT rcSrc = {nLeft, GetHeight()-nBottom, nLeft+(GetWidth()-nLeft-nRight), (GetHeight()-nBottom)+nBottom};
  272. if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))
  273. DrawImage(pDC,rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
  274. rcSrc.left, rcSrc.top,rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top);
  275. }
  276. // DrawImage(pDC,rectDest.left,rectDest.top,nWidth,m_rcNinePart.top,0,0,GetWidth(),m_rcNinePart.top);
  277. // DrawImage(pDC,rectDest.right-m_rcNinePart.right,rectDest.top-m_rcNinePart.top,m_rcNinePart.right,nHeight,GetWidth()-m_rcNinePart.right,0,m_rcNinePart.right,GetHeight());
  278. // DrawImage(pDC,rectDest.left,rectDest.bottom-m_rcNinePart.bottom,nWidth,m_rcNinePart.bottom,0,GetHeight()-m_rcNinePart.bottom,GetWidth(),m_rcNinePart.bottom);
  279. // DrawImage(pDC,rectDest.left,rectDest.top-m_rcNinePart.top,m_rcNinePart.left,nHeight,0,0,m_rcNinePart.left,GetHeight());
  280. return true;
  281. }
  282. void CImageEx::SetNinePart( CONST LPRECT lprcNinePart )
  283. {
  284. if( lprcNinePart == NULL ) return;
  285. ::CopyRect(&m_rcNinePart,lprcNinePart);
  286. }
  287. HBITMAP CImageEx::ImageToBitmap()
  288. {
  289. return (HBITMAP)*this;
  290. }
  291. bool CImageEx::DrawExtrude( CDC*pDC,const RECT& rectDest,bool bLeft,int nPixel )
  292. {
  293. //创建屏幕
  294. ASSERT(pDC!=NULL);
  295. int nWidth = rectDest.right - rectDest.left;
  296. int nHeight = rectDest.bottom - rectDest.top;
  297. if ( bLeft )
  298. {
  299. DrawImage(pDC,rectDest.left,rectDest.top);
  300. if(nWidth>GetWidth())
  301. DrawImage(pDC,GetWidth(),rectDest.top,(nWidth-GetWidth()),GetHeight(),GetWidth()-nPixel,0,nPixel,GetHeight());
  302. }
  303. else
  304. {
  305. if ( nWidth <=GetWidth() )
  306. {
  307. DrawImage(pDC,rectDest.left,rectDest.top,nWidth,GetHeight(),GetWidth()-nWidth,0,nWidth,GetHeight());
  308. }
  309. else
  310. {
  311. DrawImage(pDC,rectDest.left,rectDest.top,nWidth-GetWidth(),GetHeight(),nPixel,0,nPixel,GetHeight());
  312. DrawImage(pDC,nWidth-GetWidth(),rectDest.top);
  313. }
  314. }
  315. return true;
  316. }
  317. bool CImageEx::SetGray()
  318. {
  319. CImage *pImage = &m_ImageClone;
  320. if ( pImage == NULL && pImage->IsNull() )
  321. {
  322. pImage = this;
  323. }
  324. int nWidth = pImage->GetWidth();
  325. int nHeight = pImage->GetHeight();
  326. BYTE* pArray = (BYTE*)pImage->GetBits();
  327. int nPitch = pImage->GetPitch();
  328. int nBitCount = pImage->GetBPP() / 8;
  329. for (int i = 0; i < nHeight; i++)
  330. {
  331. for (int j = 0; j < nWidth; j++)
  332. {
  333. int grayVal = (BYTE)(((*(pArray + nPitch * i + j * nBitCount) * 306)
  334. + (*(pArray + nPitch * i + j * nBitCount + 1) * 601)
  335. + (*(pArray + nPitch * i + j * nBitCount + 2) * 117) + 512 ) >> 10); // 计算灰度值
  336. *(pArray + nPitch * i + j * nBitCount) = grayVal; // 赋灰度值
  337. *(pArray + nPitch * i + j * nBitCount + 1) = grayVal;
  338. *(pArray + nPitch * i + j * nBitCount + 2) = grayVal;
  339. }
  340. }
  341. return true;
  342. }
  343. bool CImageEx::SetAlphaBit()
  344. {
  345. ASSERT(IsNull() == false);
  346. if(IsNull())return FALSE;
  347. if ( GetBPP() == 32 )//png图像
  348. {
  349. LPVOID pBitsSrc = NULL;
  350. BYTE * psrc = NULL;
  351. BITMAP stBmpInfo;
  352. HBITMAP hBmp = (HBITMAP)*this;
  353. ::GetObject(hBmp, sizeof(BITMAP), &stBmpInfo);
  354. if (32 != stBmpInfo.bmBitsPixel || NULL == stBmpInfo.bmBits)
  355. return FALSE;
  356. psrc = (BYTE *) stBmpInfo.bmBits;
  357. for (int nPosY = 0; nPosY < abs(stBmpInfo.bmHeight); nPosY++)
  358. {
  359. for (int nPosX = stBmpInfo.bmWidth; nPosX > 0; nPosX--)
  360. {
  361. BYTE alpha = psrc[3];
  362. psrc[0] = (BYTE)((psrc[0] * alpha) / 255);
  363. psrc[1] = (BYTE)((psrc[1] * alpha) / 255);
  364. psrc[2] = (BYTE)((psrc[2] * alpha) / 255);
  365. psrc += 4;
  366. }
  367. }
  368. }
  369. return TRUE;
  370. }
  371. void CImageEx::GetImageParament( CImage *pImg,IMAGEPARAMENT *ppImgParam )
  372. {
  373. if (pImg->IsNull()) return;
  374. ppImgParam->nWidth = pImg->GetWidth(); //图像宽度
  375. ppImgParam->nHeight = pImg->GetHeight(); //图像高度
  376. ppImgParam->nBitCount = pImg->GetBPP(); //每像素位数
  377. ppImgParam->nBytesPerLine = (pImg->GetWidth()*pImg->GetBPP()+31)/32*4; //每行字节数
  378. ppImgParam->nBytesPerPixel = pImg->GetBPP()/8; //每像素字节数
  379. if (pImg->GetBPP()<=8)
  380. ppImgParam->nNumColors= 1 << pImg->GetBPP(); //调色板单元数
  381. else
  382. ppImgParam->nNumColors= 0;
  383. ppImgParam->nSize = ppImgParam->nBytesPerLine*ppImgParam->nHeight; //像素总字节数
  384. }
  385. int CImageEx::InImage( CImage *pImg,int x,int y )
  386. {
  387. IMAGEPARAMENT P;
  388. GetImageParament(pImg,&P);
  389. if ((x<0)||(y<0)||(x>=P.nWidth)||(y>=P.nHeight)) return 0;
  390. else return 1;
  391. }
  392. void CImageEx::SetRectValue(CImage *pImg,int x,int y,int Dx,int Dy,BYTE *buf )
  393. {
  394. IMAGEPARAMENT P;
  395. BYTE *lp;
  396. int i,dw,dh,x1,y1,alpha,delta,Dxb,dwb;
  397. GetImageParament(pImg,&P);
  398. if (P.nBitCount<8) return;
  399. x1=x;
  400. y1=y;
  401. alpha=delta=0;
  402. if (x<0)
  403. {
  404. alpha=-x; x1=0;
  405. }
  406. if (y<0)
  407. {
  408. delta=-y; y1=0;
  409. }
  410. if (!InImage(pImg,x1,y1)) return;
  411. dw=min(Dx,(int) P.nWidth-x1);
  412. dh=min(Dy,(int) P.nHeight-y1);
  413. dw -= alpha;
  414. dh -= delta;
  415. Dxb = Dx*P.nBytesPerPixel;
  416. dwb = dw*P.nBytesPerPixel;
  417. lp = (BYTE*) pImg->GetPixelAddress(x1,y1);
  418. buf += (delta*Dx+alpha)*P.nBytesPerPixel;
  419. for (i=0;i<dh;i++)
  420. {
  421. memcpy(lp,buf,dwb);
  422. buf += Dxb;
  423. lp -= P.nBytesPerLine;
  424. }
  425. }
  426. void CImageEx::GetAllPalette( CImage *pImg,RGBQUAD *ColorTab )
  427. {
  428. IMAGEPARAMENT P;
  429. GetImageParament(pImg,&P);
  430. pImg->GetColorTable(0, P.nNumColors, ColorTab);
  431. }
  432. void CImageEx::SetAllPalette( CImage *pImg,RGBQUAD *ColorTab )
  433. {
  434. IMAGEPARAMENT P;
  435. GetImageParament(pImg,&P);
  436. pImg->SetColorTable(0, P.nNumColors, ColorTab);
  437. }
  438. int CImageEx::PaletteType( RGBQUAD *ColorTab )
  439. {
  440. int i,k,m,n,r,g,b;
  441. m=n=0;
  442. for (i=0; i<256; i++)
  443. {
  444. r = ColorTab[i].rgbRed;
  445. g = ColorTab[i].rgbGreen;
  446. b = ColorTab[i].rgbBlue;
  447. if ((r != g)||(r != b)) m=0;
  448. if ((i>0)&&(r>ColorTab[i-1].rgbRed)) m++;
  449. if (r+g+b==0) n++;
  450. }
  451. k=3;
  452. if (m == 255) k=2;
  453. else if (256-n==1) k=0;
  454. else if (256-n==15) k=1;
  455. return(k);
  456. }
  457. int CImageEx::ImageType()
  458. {
  459. RGBQUAD ColorTab[256];
  460. int k;
  461. if (IsNull()) return(0);
  462. switch(GetBPP())
  463. {
  464. case 1: k=0; break;
  465. case 4: k=1; break;
  466. case 8: k=3; break;
  467. default: k=4; break;
  468. }
  469. if (k==3)
  470. {
  471. GetColorTable(0,256,ColorTab);
  472. k=PaletteType(ColorTab);
  473. }
  474. return(k);
  475. }
  476. void CImageEx::RotateCimage( CImage *Imgn, int nAngle )
  477. {
  478. double alpha = nAngle*3.141592654/180;
  479. IMAGEPARAMENT P;
  480. RGBQUAD ColorTab[256];
  481. int i, j, ww, Xd, Yd, Dx, Dy,nSize;
  482. double centerx, centery, sintheta, costheta;
  483. double X1, Y1, X2, Y2, theta, xx, yy, rr;
  484. BYTE **list, *sc;
  485. int x1, y1, x2, y2, flag;
  486. double p, q, a, b, c, d, t1, t2, t3;
  487. if (ImageType() == 2) flag = 1; //flag为标志位,当取值为1时,表示双线性内插法 ,此时图像类型为灰阶图像
  488. else flag = 0; //0表示最近邻点法
  489. GetImageParament(this,&P);
  490. Dx = P.nWidth;
  491. Dy = P.nHeight;
  492. nSize = 0;
  493. if (Dx < Dy)
  494. {
  495. nSize = Dy;
  496. }
  497. else
  498. {
  499. nSize = Dx;
  500. }
  501. int nLineBytes = (nSize * P.nBitCount + 31) / 32 * 4;
  502. //还有一点要修改,不然当图像高度远大于宽度时会崩溃
  503. sc = (BYTE*) malloc(2 * nLineBytes); // * P.nBytesPerLine); //申请工作单元
  504. //
  505. list = (BYTE**) malloc(Dy * sizeof(BYTE*)); //对原位图建立二维数组
  506. for (i = 0; i < Dy; i++)
  507. list[i] = (BYTE*) GetPixelAddress(0, i);
  508. centerx = Dx / 2; //计算位图中心位置
  509. centery = Dy / 2;
  510. rr = sqrt(centerx * centerx + centery *centery); //计算对角线长度
  511. theta = atan((double) centery / (double) centerx);
  512. X1 = fabs(rr * cos(alpha + theta)) + 0.5;
  513. Y1 = fabs(rr * sin(alpha + theta)) + 0.5;
  514. X2 = fabs(rr * cos(alpha - theta)) + 0.5;
  515. Y2 = fabs(rr * sin(alpha - theta)) + 0.5;
  516. if (X2 > X1) X1 = X2; //得外接矩形宽度
  517. if (Y2 > Y1) Y1 = Y2; //外接矩形高度
  518. ww = (int) (2 * X1);
  519. Imgn ->Destroy();
  520. //建立结果位图
  521. Imgn ->Create(ww, (int) (2 * Y1), P.nBitCount,CImage::createAlphaChannel );
  522. if (P.nBitCount == 8)
  523. {
  524. GetAllPalette(this,ColorTab);
  525. //修改一,设置目标调色板
  526. SetAllPalette(Imgn, ColorTab); //复制调色板
  527. }
  528. sintheta = sin(alpha);
  529. costheta = cos(alpha);
  530. for (j = (int) (centery - Y1), Yd = 0; j <= (centery + Y1); j++, Yd++)
  531. {
  532. if (P.nBitCount == 8)
  533. memset (sc, 0, ww); //256色位图像素行置背景值
  534. else memset(sc, 0, ww * P.nBytesPerPixel); //真彩色位图像素行置背景值
  535. for (i = (int) (centerx - X1), Xd = 0; i <= centerx + X1; i++, Xd += P.nBytesPerPixel)
  536. {
  537. xx = centerx + costheta * (i - centerx) + sintheta * (j - centery);
  538. yy = centery - sintheta * (i - centerx) + costheta * (j - centery);
  539. x1 = (int) xx;
  540. x2 = x1 + 1;
  541. p = xx - x1;
  542. y1 = (int) yy;
  543. y2 = y1 + 1;
  544. q = yy - y1;
  545. if (((x1 < 0)||(x2 >= P.nWidth )||(y1 < 0)||(y2 >= P.nHeight )))
  546. continue;
  547. if (flag == 0)
  548. {
  549. if (q > 0.5) y1 = y2;
  550. if (p > 0.5) x1 = x2;
  551. //修改二, sc[Xd]
  552. memcpy(&sc[Xd], &list[y1][x1 * P.nBytesPerPixel], P.nBytesPerPixel); //从源位图复制像素数据
  553. }
  554. else
  555. { // flag等于1,双线性内插法
  556. a = (double) list[y1][x1]; //从源位图取数据
  557. b = (double) list[y1][x2];
  558. c = (double) list[y2][x1];
  559. d = (double) list[y2][x2];
  560. t1 = (1 - p) * a + p * b; //双线性内插计算
  561. t2 = (1 - p) * c + p * d;
  562. t3 = (1 - q) * t1 + q * t2;
  563. //修改三
  564. sc[Xd] = (BYTE) t3;
  565. }
  566. }
  567. SetRectValue(Imgn, 0, Yd, ww, 1, sc);
  568. }
  569. //png图像
  570. if ( P.nBitCount == 32 )
  571. {
  572. LPVOID pBitsSrc = NULL;
  573. BYTE * psrc = NULL;
  574. BITMAP stBmpInfo;
  575. HBITMAP hBmp = (HBITMAP)m_ImageClone;
  576. ::GetObject(hBmp, sizeof(BITMAP), &stBmpInfo);
  577. if (32 != stBmpInfo.bmBitsPixel || NULL == stBmpInfo.bmBits)
  578. return;
  579. psrc = (BYTE *) stBmpInfo.bmBits;
  580. for (int nPosY = 0; nPosY < abs(stBmpInfo.bmHeight); nPosY++)
  581. {
  582. for (int nPosX = stBmpInfo.bmWidth; nPosX > 0; nPosX--)
  583. {
  584. BYTE alpha = psrc[3];
  585. psrc[0] = (BYTE)((psrc[0] * alpha) / 255);
  586. psrc[1] = (BYTE)((psrc[1] * alpha) / 255);
  587. psrc[2] = (BYTE)((psrc[2] * alpha) / 255);
  588. psrc += 4;
  589. }
  590. }
  591. }
  592. free(list); //释放工作单元
  593. free(sc);
  594. }
  595. void CImageEx::SetRotation( int nAngle )
  596. {
  597. if ( nAngle == 0 ) return;
  598. m_ImageClone.Destroy();
  599. RotateCimage(&m_ImageClone,nAngle);
  600. }
  601. //////////////////////////////////////////////////////////////////////////////////