IMGCommon.cpp 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899
  1. #include "StdAfx.h"
  2. #include "IMGCommon.h"
  3. #include "IMGkernelGlobal.h"
  4. #include <strsafe.h>
  5. #include "StringProcess.h"
  6. const ColorMatrix _ClrMatrix =
  7. {
  8. 1.0, 0.0, 0.0, 0.0, 0.0,
  9. 0.0, 1.0, 0.0, 0.0, 0.0,
  10. 0.0, 0.0, 0.3, 0.0, 0.0,
  11. 0.0, 0.0, 0.0, 1.0, 0.0,
  12. 0.0, 0.0, 0.0, 0.0, 1.0,
  13. };
  14. ULONG_PTR IMGCommon::m_gdiplusToken;
  15. IMGCommon::IMGCommon(void)
  16. {
  17. GdiplusStartupInput gdiplusStartupInput;
  18. GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
  19. }
  20. IMGCommon::~IMGCommon(void)
  21. {
  22. Gdiplus::GdiplusShutdown(m_gdiplusToken);
  23. }
  24. /************************************************************************/
  25. /* 函数:IsCorrectExt[6/1/2016 IT];
  26. /* 描述:扩展名是否正确;
  27. /* 参数:;
  28. /* [IN] fext:要判断的扩展名;
  29. /* [OUT] lpMistakenExt:返回错误的扩展名;
  30. /* 返回:扩展名错误返回-1、扩展名为*.*返回0、扩展符合要求返回1;
  31. /* 注意:;
  32. /* 示例:;
  33. /*
  34. /* 修改:;
  35. /* 日期:;
  36. /* 内容:;
  37. /************************************************************************/
  38. INT IMGCommon::IsCorrectExt( IN const TString &fext, OUT TString* lpMistakenExt /* = NULL */ )
  39. {
  40. if (fext.size() == 0)
  41. {
  42. IMGkernelGlobal::WriteTextLog(_T("要查找的扩展名字符空!"));
  43. return -1;
  44. }
  45. if (fext.find(_T("*.*")) != TString::npos)
  46. {
  47. IMGkernelGlobal::WriteTextLog(_T("要查找的扩展名为\"*.*\""));
  48. return 0;
  49. }
  50. TString ext = IMGkernelGlobal::lowercase(fext);
  51. if (ext[ext.length() - 1] != _T('|'))
  52. ext.append(_T("|"));
  53. INT bRet = 1;
  54. CONST TString sCorrectExt = _T("*.jpg|*.jpeg|*.png|*.bmp|*.cr2|*.nef|*.raw|*.ra2|*.ofr|*.pef|*.sr2");
  55. int nIndex = 0;
  56. do
  57. {
  58. nIndex = ext.find(_T('|'));
  59. if (nIndex != TString::npos)
  60. {
  61. if (sCorrectExt.find(ext.substr(0, nIndex)) == TString::npos)
  62. {
  63. if (lpMistakenExt)
  64. *lpMistakenExt = ext.substr(0, nIndex);
  65. bRet = -1;
  66. break;
  67. }
  68. ext = ext.substr(nIndex + 1);
  69. }
  70. } while (ext.find(_T('|')) != TString::npos);
  71. return bRet;
  72. }
  73. /************************************************************************/
  74. /* 函数:ExtMerge[6/1/2016 IT];
  75. /* 描述:合并扩展名;
  76. /* 参数:;
  77. /* [IN] ext1:要合并的扩展名1;
  78. /* [IN] ext2:要合并的扩展名2;
  79. /* [OUT] merge:合并后的扩展名;
  80. /* 返回:只合并合法的扩展名,若两扩展名都非法,返回FALSE;
  81. /* 注意:;
  82. /* 示例:;
  83. /*
  84. /* 修改:;
  85. /* 日期:;
  86. /* 内容:;
  87. /************************************************************************/
  88. BOOL IMGCommon::ExtMerge(IN CONST TString& ext1, IN CONST TString& ext2, OUT TString &merge) // 合并扩展名;
  89. {
  90. // 1.判断扩展名1合法性;
  91. INT nRet = IsCorrectExt(ext1);
  92. if ( nRet == -1 )
  93. {
  94. nRet = IsCorrectExt(ext2);
  95. if ( nRet == -1)
  96. return FALSE;
  97. merge = ext2;
  98. return TRUE;
  99. }
  100. if (nRet == 0)
  101. {
  102. merge = _T("*.*");
  103. return TRUE;
  104. }
  105. merge = ext1;
  106. // 2.判断扩展名2合法性;
  107. nRet = IsCorrectExt(ext2);
  108. if (nRet != 1) return TRUE;
  109. // 3.合并2扩展名;
  110. if (merge[merge.length() - 1] != _T('|'))
  111. merge.append(_T("|"));
  112. merge.append(ext2);
  113. return TRUE;
  114. }
  115. /************************************************************************/
  116. /* 函数:GetFileName[6/1/2016 IT];
  117. /* 描述:根据参数,获取参数中的文件名;
  118. /* 参数:;
  119. /* [IN] strfile:要获取文件名的全路径名;
  120. /* 返回:获取成功返回文件名,否则返回空;
  121. /* 注意:;
  122. /* 示例:;
  123. /*
  124. /* 修改:;
  125. /* 日期:;
  126. /* 内容:;
  127. /************************************************************************/
  128. CString IMGCommon::GetFileName(IN CONST CString& strfile)
  129. {
  130. CString name = _T("");
  131. int nIndex = strfile.ReverseFind(_T('\\'));
  132. if (nIndex == -1)
  133. return _T("");
  134. name = strfile.Mid(nIndex + 1);
  135. nIndex = name.ReverseFind(_T('.'));
  136. if (nIndex == -1)
  137. return _T("");
  138. name = name.Mid(0, nIndex);
  139. return name;
  140. }
  141. /************************************************************************/
  142. /* 函数:GetFilteringImg[6/1/2016 IT];
  143. /* 描述:过滤掉扩展名不符合要求的文件名;
  144. /* 参数:;
  145. /* [IN] AryImgs:要被过滤的文件名数组;
  146. /* [IN] lpCopyExt:要保留的文件的扩展名;
  147. /* [IN] bPickoutThumbnail:是否剔除缩略图;
  148. /* 返回:void;
  149. /* 注意:;
  150. /* 示例:;
  151. /*
  152. /* 修改:;
  153. /* 日期:;
  154. /* 内容:;
  155. /************************************************************************/
  156. void IMGCommon::GetFilteringImg(IN CStringArray &AryImgs, IN LPCTSTR lpCopyExt, IN BOOL bPickoutThumbnail /*= TRUE*/)
  157. {
  158. if (AryImgs.GetSize() == 0 || lpCopyExt == NULL) return;
  159. // 获取复制扩展名;
  160. int nIndex = 0;
  161. TString strtmp;
  162. TString strCopyExt(lpCopyExt);
  163. if (strCopyExt.find(_T("*.*")) != TString::npos) return;
  164. strCopyExt.append(_T("|"));
  165. STR_VEC vtCopyExt;
  166. // 将所有扩展名解析到数组里;
  167. do
  168. {
  169. nIndex = strCopyExt.find(_T('|'));
  170. if (nIndex != TString::npos)
  171. {
  172. strtmp = strCopyExt.substr(0, nIndex);
  173. strCopyExt = strCopyExt.substr(nIndex + 1);
  174. if (strtmp.compare(_T("*.*")))
  175. vtCopyExt.push_back(strtmp.substr(1));
  176. }
  177. } while (strCopyExt.find(_T('|')) != TString::npos);
  178. // 过滤非复制扩展名的文件,同时去掉缩略图,保留指定复制扩展名的文件;
  179. for (int i = AryImgs.GetSize() - 1; i >= 0; i--)
  180. {
  181. BOOL bExsit = FALSE;
  182. for (STR_VEC::iterator itExt = vtCopyExt.begin(); itExt != vtCopyExt.end(); itExt++)
  183. {
  184. if (AryImgs.ElementAt(i).MakeLower().Find(itExt->c_str()) != -1) {
  185. bExsit = TRUE;
  186. break;
  187. }
  188. }
  189. if (!bExsit) {
  190. AryImgs.RemoveAt(i);
  191. continue;
  192. }
  193. if (bPickoutThumbnail)
  194. {// 这里应该去除"s"和"m"开头的缩略图;// 但新的做法是在订单里创建缩略图子文件夹;// 总而言之,都要去掉缩略图;
  195. nIndex = AryImgs.ElementAt(i).ReverseFind(_T('\\'));
  196. if (nIndex != -1)
  197. {
  198. strtmp = AryImgs.ElementAt(i).Mid(nIndex + 1);
  199. if (strtmp[0] == _T('s') || strtmp[0] == _T('m')) {
  200. AryImgs.RemoveAt(i);
  201. continue;
  202. }
  203. }
  204. }
  205. }
  206. }
  207. /************************************************************************/
  208. /* 函数:GetFilteringImg[6/1/2016 IT];
  209. /* 描述:过滤掉扩展名不符合要求的文件名;
  210. /* 参数:;
  211. /* [IN] vtImgs:要被过滤的文件名数组;
  212. /* [IN] lpCopyExt:要保留的文件的扩展名;
  213. /* [IN] bPickoutThumbnail:是否剔除缩略图;
  214. /* 返回:void;
  215. /* 注意:;
  216. /* 示例:;
  217. /*
  218. /* 修改:;
  219. /* 日期:;
  220. /* 内容:;
  221. /************************************************************************/
  222. void IMGCommon::GetFilteringImg(IN STR_VEC &vtImgs, IN LPCTSTR lpCopyExt, IN BOOL bPickoutThumbnail /*= TRUE*/)
  223. {
  224. if (vtImgs.size() == 0 || lpCopyExt == NULL) return;
  225. // 获取复制扩展名;
  226. int nIndex = 0;
  227. TString strtmp;
  228. TString strCopyExt(lpCopyExt);
  229. if (strCopyExt.find(_T("*.*")) != TString::npos) return;
  230. strCopyExt.append(_T("|"));
  231. STR_VEC vtCopyExt;
  232. // 将所有扩展名解析到数组里;
  233. do
  234. {
  235. nIndex = strCopyExt.find(_T('|'));
  236. if (nIndex != TString::npos)
  237. {
  238. strtmp = strCopyExt.substr(0, nIndex);
  239. strCopyExt = strCopyExt.substr(nIndex + 1);
  240. if (strtmp.compare(_T("*.*")))
  241. vtCopyExt.push_back(strtmp);
  242. }
  243. } while (strCopyExt.find(_T('|')) != TString::npos);
  244. // 过滤非复制扩展名的文件,同时去掉缩略图,保留指定复制扩展名的文件;
  245. for (STR_VEC::iterator it = vtImgs.begin(); it != vtImgs.end();)
  246. {
  247. BOOL bExsit = FALSE;
  248. for (STR_VEC::iterator itExt = vtCopyExt.begin(); itExt != vtCopyExt.end(); itExt++)
  249. {
  250. if (IMGkernelGlobal::match(itExt->c_str(), it->c_str())) {
  251. bExsit = TRUE;
  252. break;
  253. }
  254. }
  255. if (!bExsit) {
  256. it = vtImgs.erase(it);
  257. continue;
  258. }
  259. if (bPickoutThumbnail)
  260. {// 这里应该去除"s"和"m"开头的缩略图;// 但新的做法是在订单里创建缩略图子文件夹;// 总而言之,都要去掉缩略图;
  261. nIndex = it->find_last_of(_T('\\'));
  262. if (nIndex != TString::npos) {
  263. strtmp = it->substr(nIndex + 1);
  264. if (strtmp[0] == _T('s') || strtmp[0] == _T('m')) {
  265. it = vtImgs.erase(it);
  266. continue;
  267. }
  268. }
  269. }
  270. it++;
  271. }
  272. }
  273. /************************************************************************/
  274. /* 函数:SubgroupExt[6/1/2016 IT];
  275. /* 描述:将指定的扩展名文件分离出来;
  276. /* 参数:;
  277. /* [IN] vtAllImgs:源,要被分离指定扩展名的文件路径数组;
  278. /* [IN] lpSubgroupExt:要分离出来的扩展名;
  279. /* [OUT] AryImgs:返回分离出来的文件路径数组;
  280. /* 返回:void;
  281. /* 注意:;
  282. /* 示例:;
  283. /*
  284. /* 修改:;
  285. /* 日期:;
  286. /* 内容:;
  287. /************************************************************************/
  288. void IMGCommon::SubgroupExt(IN STR_VEC &vtAllImgs, IN LPCTSTR lpSubgroupExt, OUT CStringArray &AryImgs)
  289. {
  290. if (vtAllImgs.size() == 0 || lpSubgroupExt == NULL) return;
  291. // 获取复制扩展名;
  292. int nIndex = 0;
  293. TString strtmp;
  294. TString strSubgroupExt(lpSubgroupExt);
  295. if (strSubgroupExt.find(_T("*.*")) != TString::npos)
  296. {
  297. for (STR_VEC::iterator it = vtAllImgs.begin(); it != vtAllImgs.end(); it++)
  298. AryImgs.Add(CString(it->c_str()));
  299. return;
  300. }
  301. strSubgroupExt.append(_T("|"));
  302. STR_VEC vtSubgroupExt;
  303. // 将所有扩展名解析到数组里;
  304. do
  305. {
  306. nIndex = strSubgroupExt.find(_T('|'));
  307. if (nIndex != TString::npos)
  308. {
  309. strtmp = strSubgroupExt.substr(0, nIndex);
  310. strSubgroupExt = strSubgroupExt.substr(nIndex + 1);
  311. if (strtmp.compare(_T("*.*")))
  312. vtSubgroupExt.push_back(strtmp);
  313. }
  314. } while (strSubgroupExt.find(_T('|')) != TString::npos);
  315. // 过滤非复制扩展名的文件,同时去掉缩略图,保留指定复制扩展名的文件;
  316. for (STR_VEC::iterator it = vtAllImgs.begin(); it != vtAllImgs.end(); it++)
  317. {
  318. BOOL bExsit = FALSE;
  319. for (STR_VEC::iterator itExt = vtSubgroupExt.begin(); itExt != vtSubgroupExt.end(); itExt++)
  320. {
  321. if (IMGkernelGlobal::match(itExt->c_str(), it->c_str()))
  322. {
  323. #if 1// 这里应该去除"s"和"m"开头的缩略图;// 但新的做法是在订单里创建缩略图子文件夹;// 总而言之,都要去掉缩略图;
  324. nIndex = it->find_last_of(_T('\\'));
  325. if (nIndex != TString::npos)
  326. {
  327. strtmp = it->substr(nIndex + 1);
  328. if (strtmp[0] == _T('s') || strtmp[0] == _T('m'))
  329. {
  330. continue;
  331. }
  332. }
  333. #endif
  334. AryImgs.Add(CString(it->c_str()));
  335. break;
  336. }
  337. }
  338. }
  339. }
  340. void IMGCommon::SubgroupExt(IN STR_VEC &vtAllImgs, IN LPCTSTR lpSubgroupExt, IN STR_VEC &vtImgs)
  341. {
  342. if (vtAllImgs.size() == 0 || lpSubgroupExt == NULL) return;
  343. // 获取复制扩展名;
  344. int nIndex = 0;
  345. TString strtmp;
  346. TString strSubgroupExt(lpSubgroupExt);
  347. if (strSubgroupExt.find(_T("*.*")) != TString::npos)
  348. {
  349. for (STR_VEC::iterator it = vtAllImgs.begin(); it != vtAllImgs.end(); it++)
  350. vtImgs.push_back(*it);
  351. return;
  352. }
  353. strSubgroupExt.append(_T("|"));
  354. STR_VEC vtSubgroupExt;
  355. // 将所有扩展名解析到数组里;
  356. do
  357. {
  358. nIndex = strSubgroupExt.find(_T('|'));
  359. if (nIndex != TString::npos)
  360. {
  361. strtmp = strSubgroupExt.substr(0, nIndex);
  362. strSubgroupExt = strSubgroupExt.substr(nIndex + 1);
  363. if (strtmp.compare(_T("*.*")))
  364. vtSubgroupExt.push_back(strtmp);
  365. }
  366. } while (strSubgroupExt.find(_T('|')) != TString::npos);
  367. // 过滤非复制扩展名的文件,同时去掉缩略图,保留指定复制扩展名的文件;
  368. for (STR_VEC::iterator it = vtAllImgs.begin(); it != vtAllImgs.end(); it++)
  369. {
  370. BOOL bExsit = FALSE;
  371. for (STR_VEC::iterator itExt = vtSubgroupExt.begin(); itExt != vtSubgroupExt.end(); itExt++)
  372. {
  373. if (IMGkernelGlobal::match(itExt->c_str(), it->c_str())) {
  374. #if 1// 这里应该去除"s"和"m"开头的缩略图;// 但新的做法是在订单里创建缩略图子文件夹;// 总而言之,都要去掉缩略图;
  375. nIndex = it->find_last_of(_T('\\'));
  376. if (nIndex != TString::npos) {
  377. strtmp = it->substr(nIndex + 1);
  378. if (strtmp[0] == _T('s') || strtmp[0] == _T('m')) {
  379. continue;
  380. }
  381. }
  382. #endif
  383. vtImgs.push_back(*it);
  384. break;
  385. }
  386. }
  387. }
  388. }
  389. //////////////////////////////////////////////////////////////////////////
  390. BOOL IMGCommon::LoadImgFromFile(IN Image** pImg, LPCTSTR lpPath)
  391. {
  392. if ( !PathFileExists(lpPath) )
  393. return FALSE;
  394. if ( *pImg )
  395. delete *pImg;
  396. *pImg = NULL;
  397. #ifdef UNICODE
  398. *pImg = Image::FromFile(lpPath);
  399. #else
  400. BSTR strtmp = _bstr_t(lpPath);
  401. *pImg = Image::FromFile(strtmp, TRUE);
  402. SysFreeString(strtmp);
  403. #endif
  404. return (*pImg ? TRUE : FALSE);
  405. }
  406. BOOL IMGCommon::LoadImgFromBuffer(IN Image** pImg, IN BYTE* pBuffer, IN CONST INT& nBufLen)
  407. {
  408. if ( pBuffer == NULL )
  409. return FALSE;
  410. if ( *pImg )
  411. delete *pImg;
  412. *pImg = NULL;
  413. HGLOBAL hMemery = GlobalAlloc(GMEM_MOVEABLE, nBufLen);
  414. if ( hMemery == NULL )
  415. return FALSE;
  416. BYTE *pMem = (BYTE*)GlobalLock(hMemery);
  417. memcpy(pMem, pBuffer, nBufLen);
  418. IStream *pstream = NULL;
  419. CreateStreamOnHGlobal(hMemery, TRUE, &pstream);
  420. *pImg = Image::FromStream(pstream);
  421. GlobalUnlock(hMemery);
  422. pstream->Release();
  423. return (*pImg ? TRUE : FALSE);
  424. }
  425. // 先以只读方式从文件中读取二进制流出来,可以做到不独占文件;
  426. BOOL IMGCommon::LoadImgFromBuffer(IN Image** pImg, LPCTSTR lpPath)
  427. {
  428. if ( !PathFileExists(lpPath) )
  429. return FALSE;
  430. if ( *pImg )
  431. delete *pImg;
  432. *pImg = NULL;
  433. return LoadImgFromFile(pImg, lpPath);
  434. CFile fp;
  435. CFileException e;
  436. BOOL bRet = FALSE;
  437. if ( fp.Open(lpPath, CFile::modeRead, &e))
  438. {
  439. DWORD dwLength = (DWORD)fp.GetLength();
  440. BYTE *pData = new BYTE[dwLength];
  441. fp.Read(pData,dwLength);
  442. fp.Close();
  443. bRet = LoadImgFromBuffer(pImg, pData, dwLength);
  444. if( pData )
  445. delete []pData;
  446. }
  447. return bRet;
  448. }
  449. /************************************************************************/
  450. /* 函数:LoadImgFromResource[9/21/2016 IT];
  451. /* 描述:从资源中加载;
  452. /* 参数:;
  453. /* [IN] :;
  454. /* [OUT] :;
  455. /* [IN/OUT] :;
  456. /* 返回:void;
  457. /* 注意:;
  458. /* 示例:;
  459. /*
  460. /* 修改:;
  461. /* 日期:;
  462. /* 内容:;
  463. /************************************************************************/
  464. Image* IMGCommon::LoadImgFromResource(IN HMODULE hModule, IN LPCTSTR lpName, IN LPCTSTR lpType)
  465. {
  466. HGLOBAL hGlobal = NULL;
  467. HRSRC hSource = NULL;
  468. LPVOID lpBuffer = NULL;
  469. DWORD dwSize = 0;
  470. // 1.定位我们的自定义资源,这里因为我们是从本模块定位资源,所以将句柄简单地置为NULL即可
  471. hSource = FindResource(hModule, lpName, lpType);
  472. if (hSource == NULL)
  473. {
  474. _tprintf(_T("载入资源失败:%s"), lpName);
  475. return NULL;
  476. }
  477. // 2.获取资源的大小;
  478. dwSize = (UINT)SizeofResource(NULL, hSource);
  479. // 3.加载资源;
  480. hGlobal = LoadResource(NULL, hSource);
  481. if (hGlobal == NULL)
  482. {
  483. _tprintf(_T("载入资源失败:%s"), lpName);
  484. return NULL;
  485. }
  486. // 4.锁定资源,获取buffer;
  487. lpBuffer = LockResource(hGlobal);
  488. if (lpBuffer == NULL)
  489. {
  490. _tprintf(_T("载入资源失败:%s"), lpName);
  491. return NULL;
  492. }
  493. // lpFileFullName需要先判断文件是否存在??不需要;
  494. Image *pImg = NULL;
  495. LoadImgFromBuffer(&pImg, (BYTE*)lpBuffer, dwSize);
  496. UnlockResource(hGlobal);
  497. FreeResource(hGlobal);
  498. return pImg;
  499. }
  500. /*
  501. BOOL IMGCommon::LoadImgFromFile(IN Bitmap** pImg, LPCTSTR lpPath)
  502. {
  503. if ( !PathFileExists(lpPath) )
  504. return FALSE;
  505. if ( *pImg )
  506. delete *pImg;
  507. *pImg = NULL;
  508. #ifdef UNICODE
  509. *pImg = Bitmap::FromFile(lpPath);
  510. #else
  511. BSTR strtmp = _bstr_t(lpPath);
  512. *pImg = Bitmap::FromFile(strtmp);
  513. SysFreeString(strtmp);
  514. #endif
  515. return TRUE;
  516. }
  517. BOOL IMGCommon::LoadImgFromBuffer(IN Bitmap** pImg, IN BYTE* pBuffer, IN CONST INT& nBufLen)
  518. {
  519. if ( pBuffer == NULL )
  520. return FALSE;
  521. if ( *pImg )
  522. delete *pImg;
  523. *pImg = NULL;
  524. HGLOBAL hMemery = GlobalAlloc(GMEM_MOVEABLE, nBufLen);
  525. if ( hMemery == NULL )
  526. return FALSE;
  527. BYTE *pMem = (BYTE*)GlobalLock(hMemery);
  528. memcpy(pMem, pBuffer, nBufLen);
  529. IStream *pstream = NULL;
  530. CreateStreamOnHGlobal(hMemery, TRUE, &pstream);
  531. *pImg = Bitmap::FromStream(pstream);
  532. GlobalUnlock(hMemery);
  533. pstream->Release();
  534. return TRUE;
  535. }
  536. */
  537. //////////////////////////////////////////////////////////////////////////
  538. BOOL IMGCommon::GetOrientation(IN Image *pImg)
  539. {
  540. if (pImg == NULL) return FALSE;
  541. UINT totalBufferSize;
  542. UINT numProperties;
  543. pImg->GetPropertySize(&totalBufferSize, &numProperties);
  544. // Allocate the buffer that will receive the property items.
  545. PropertyItem* pAllItems = (PropertyItem*)malloc(totalBufferSize);
  546. // Fill the buffer.
  547. pImg->GetAllPropertyItems(totalBufferSize, numProperties, pAllItems);
  548. // Print the id data member of each property item.
  549. for (UINT j = 0; j < numProperties; ++j)
  550. {
  551. if (PropertyTagOrientation == pAllItems[j].id)
  552. {
  553. short* ptrLong = (short*)(pAllItems[j].value);
  554. int ret = (int)*ptrLong;
  555. free(pAllItems);
  556. return ret;
  557. }
  558. }
  559. free(pAllItems);
  560. return TRUE;
  561. }
  562. /************************************************************************/
  563. /*
  564. 函数:GetEncoderClsid
  565. 描述:获取GDI+支持的图像格式编码器种类,以及所有种类编码器信息;
  566. 参数:
  567. IN: format 要获取的图像格式;
  568. OUT: pClsid 返回符合条件的图像编码器信息;
  569. 返回:成功返回编码器索引,否则返回-1;
  570. */
  571. /************************************************************************/
  572. int IMGCommon::GetEncoderClsid(IN CONST WCHAR* format, OUT CLSID* pClsid)
  573. {
  574. // GDI+支持的图像编码器数量;
  575. UINT numEncoders = 0;
  576. // GDI+所有图像格式编码器详细信息所需要的空间大小;
  577. UINT nSize = 0;
  578. ImageCodecInfo* pImageCodecInfo = NULL;
  579. // 2.获取GDI+支持的所有图像格式编码器详细信息所需要的空间大小;
  580. GetImageEncodersSize(&numEncoders, &nSize);
  581. if (nSize == 0)
  582. return -1;
  583. //3.为ImageCodecInfo数组分配足额空间;
  584. pImageCodecInfo = (ImageCodecInfo*)(malloc(nSize));
  585. if (pImageCodecInfo == NULL)
  586. return -1;
  587. //4.获取所有的图像编码器信息;
  588. GetImageEncoders(numEncoders, nSize, pImageCodecInfo);
  589. //5.查找符合的图像编码器的Clsid;
  590. for (UINT i = 0; i < numEncoders; ++i)
  591. {
  592. if (wcscmp(pImageCodecInfo[i].MimeType, format) == 0)
  593. {
  594. *pClsid = pImageCodecInfo[i].Clsid;
  595. free(pImageCodecInfo);
  596. return i; // Success
  597. }
  598. }
  599. //6.释放步骤3分配的内存;
  600. free(pImageCodecInfo);
  601. return -1;
  602. }
  603. /************************************************************************/
  604. /*
  605. 函数:SaveImg2newfile
  606. 描述:将Image对象另存为其他格式的文件;
  607. 参数:
  608. IN: pImg GDI+ Image对象指针,需要保存的图像对象;
  609. IN: lpnewfile 其他格式的新文件名(jpg,bmp,png,jpeg);
  610. IN: uQuality 另存为新文件时的图像质量值;
  611. 返回:
  612. 注意:Image::Save 若文件存在,会覆盖存在的文件;
  613. */
  614. /************************************************************************/
  615. BOOL IMGCommon::SaveImg2newfile(IN Image* pImg, IN CString strNewfile, IN ULONG uQuality)
  616. {
  617. if (pImg == NULL) return FALSE;
  618. // 需要判断路径是否存在,不存在创建目录;
  619. int nIndex = strNewfile.ReverseFind(_T('\\'));
  620. if (nIndex == -1)
  621. return FALSE;
  622. if (!PathFileExists(strNewfile.Left(nIndex)))
  623. {
  624. // 如果文件夹不存在,创建;
  625. SHCreateDirectoryEx(NULL, strNewfile.Left(nIndex), NULL);
  626. }
  627. nIndex = strNewfile.ReverseFind(_T('.'));
  628. if (nIndex == -1)
  629. return FALSE;
  630. Status stat = GenericError;
  631. CLSID encoderClsid = { 0 };
  632. BSTR newfile = strNewfile.AllocSysString();
  633. strNewfile = strNewfile.Mid(nIndex + 1);
  634. if (strNewfile.CompareNoCase(_T("bmp")) == 0)
  635. {
  636. GetEncoderClsid(L"image/bmp", &encoderClsid);
  637. stat = pImg->Save(newfile, &encoderClsid, NULL);
  638. }
  639. else if (strNewfile.CompareNoCase(_T("png")) == 0)
  640. {
  641. GetEncoderClsid(L"image/png", &encoderClsid);
  642. stat = pImg->Save(newfile, &encoderClsid, NULL);
  643. }
  644. else// if ( strNewfile.CompareNoCase(_T("jpeg")) == 0 )
  645. {
  646. GetEncoderClsid(L"image/jpeg", &encoderClsid);
  647. EncoderParameters encoderParameters;
  648. encoderParameters.Count = 1;
  649. encoderParameters.Parameter[0].Guid = EncoderQuality;
  650. encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
  651. encoderParameters.Parameter[0].NumberOfValues = 1;
  652. // Save the image as a JPEG with quality level 100.
  653. encoderParameters.Parameter[0].Value = &uQuality;
  654. stat = pImg->Save(newfile, &encoderClsid, &encoderParameters);
  655. }
  656. SysFreeString(newfile);
  657. return stat == Ok ? TRUE : FALSE;
  658. }
  659. BOOL IMGCommon::SaveImg2newfile(IN Image* pImg, IN TString strNewfile, IN ULONG uQuality)
  660. {
  661. if (pImg == NULL) return FALSE;
  662. // 需要判断路径是否存在,不存在创建目录;
  663. int nIndex = strNewfile.find_last_of(_T('\\'));
  664. if (nIndex == TString::npos)
  665. return FALSE;
  666. if (!PathFileExists(strNewfile.substr(0, nIndex).c_str()))
  667. {
  668. // 如果文件夹不存在,创建;
  669. SHCreateDirectoryEx(NULL, strNewfile.substr(0, nIndex).c_str(), NULL);
  670. }
  671. nIndex = strNewfile.find_last_of(_T('.'));
  672. if (nIndex == TString::npos)
  673. return FALSE;
  674. Status stat = GenericError;
  675. CLSID encoderClsid = { 0 };
  676. BSTR newfile = _bstr_t(strNewfile.c_str());
  677. strNewfile = strNewfile.substr(nIndex + 1);
  678. if (strNewfile.find(_T("bmp")) == 0)
  679. {
  680. GetEncoderClsid(L"image/bmp", &encoderClsid);
  681. stat = pImg->Save(newfile, &encoderClsid, NULL);
  682. }
  683. else if (strNewfile.find(_T("png")) == 0)
  684. {
  685. GetEncoderClsid(L"image/png", &encoderClsid);
  686. stat = pImg->Save(newfile, &encoderClsid, NULL);
  687. }
  688. else// if ( strNewfile.CompareNoCase(_T("jpeg")) == 0 )
  689. {
  690. GetEncoderClsid(L"image/jpeg", &encoderClsid);
  691. EncoderParameters encoderParameters;
  692. encoderParameters.Count = 1;
  693. encoderParameters.Parameter[0].Guid = EncoderQuality;
  694. encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
  695. encoderParameters.Parameter[0].NumberOfValues = 1;
  696. // Save the image as a JPEG with quality level 100.
  697. encoderParameters.Parameter[0].Value = &uQuality;
  698. stat = pImg->Save(newfile, &encoderClsid, &encoderParameters);
  699. }
  700. SysFreeString(newfile);
  701. return stat == Ok ? TRUE : FALSE;
  702. }
  703. /************************************************************************/
  704. /*
  705. 函数:ZoomImg
  706. 描述:缩放到指定大小的区域中,返回缩放后的尺寸;
  707. 参数:
  708. IN: Imgrc 图像的大小;
  709. IN: dwDisplayPix 图像要显示的区域的大小;
  710. OUT: dwZoomPix 图像在显示区域内缩放后的尺寸;
  711. 返回:
  712. 注意:dwZoomPix的尺寸必须在dwDisplayPix内;
  713. */
  714. /************************************************************************/
  715. int IMGCommon::ZoomImg(IN CRect &Imgrc, IN CONST DWORD &dwDisplayPix, OUT DWORD &dwZoomPix)
  716. {
  717. double fDisplayWidth = GET_XPIX(dwDisplayPix);
  718. double fDisplayHeight = GET_YPIX(dwDisplayPix);
  719. // 显示区域长宽比;
  720. double fDisplayAspectRatio = fDisplayWidth / fDisplayHeight;
  721. // 图片长宽比;
  722. double fImgAspectRatio = ((double)Imgrc.Width()) / ((double)Imgrc.Height());
  723. double fZoomWidth;
  724. double fZoomHeight;
  725. if (fDisplayAspectRatio > fImgAspectRatio)
  726. {
  727. fZoomWidth = fDisplayHeight*fImgAspectRatio;
  728. fZoomHeight = fDisplayHeight;
  729. }
  730. else
  731. {
  732. fZoomWidth = fDisplayWidth;
  733. fZoomHeight = fDisplayWidth / fImgAspectRatio;
  734. }
  735. dwZoomPix = SET_PIX((int)fZoomWidth, (int)fZoomHeight);
  736. //////////////////////////////////////////////////////////////////////////
  737. int nRetval = 0;
  738. if ((fDisplayWidth == Imgrc.Width()) && (fDisplayHeight == Imgrc.Height()))
  739. {
  740. nRetval = ZoomNull;
  741. }
  742. else if ((fDisplayWidth > Imgrc.Width()) && (fDisplayHeight > Imgrc.Height()))
  743. {
  744. nRetval = ZoomOut;
  745. }
  746. else
  747. {
  748. nRetval = ZoomIn;
  749. }
  750. return nRetval;
  751. }
  752. int IMGCommon::ZoomImg(IN CONST DWORD &dwImgPix, IN CONST DWORD &dwDisplayPix, OUT DWORD &dwZoomPix)
  753. {
  754. double fDisplayWidth = GET_XPIX(dwDisplayPix);
  755. double fDisplayHeight = GET_YPIX(dwDisplayPix);
  756. // 显示区域长宽比;
  757. double fDisplayAspectRatio = fDisplayWidth / fDisplayHeight;
  758. // 图片长宽比;
  759. double fImgAspectRatio = ((double)GET_XPIX(dwImgPix)) / ((double)GET_YPIX(dwImgPix));
  760. double fZoomWidth;
  761. double fZoomHeight;
  762. if (fDisplayAspectRatio > fImgAspectRatio)
  763. {
  764. fZoomWidth = fDisplayHeight*fImgAspectRatio;
  765. fZoomHeight = fDisplayHeight;
  766. }
  767. else
  768. {
  769. fZoomWidth = fDisplayWidth;
  770. fZoomHeight = fDisplayWidth / fImgAspectRatio;
  771. }
  772. dwZoomPix = SET_PIX((int)fZoomWidth, (int)fZoomHeight);
  773. //////////////////////////////////////////////////////////////////////////
  774. int nRetval = 0;
  775. if ((fDisplayWidth == GET_XPIX(dwImgPix)) && (fDisplayHeight == GET_YPIX(dwImgPix)))
  776. {
  777. nRetval = ZoomNull;
  778. }
  779. else if ((fDisplayWidth > GET_XPIX(dwImgPix)) && (fDisplayHeight > GET_YPIX(dwImgPix)))
  780. {
  781. nRetval = ZoomOut;
  782. }
  783. else
  784. {
  785. nRetval = ZoomIn;
  786. }
  787. return nRetval;
  788. }
  789. /************************************************************************/
  790. /*
  791. 函数:ImgThumbnail
  792. 描述:生成高质量的图像缩略图;
  793. 参数:
  794. 返回:
  795. 注意:为了健壮性,strNewfile的路径可以在函数内再次判断是否有效,防止在函数外没有进行经判断;
  796. */
  797. /************************************************************************/
  798. BOOL IMGCommon::ImgThumbnail(IN Image* pImg, IN CONST DWORD &dwDisplayPix, IN CString strNewfile, IN ULONG uQuality)
  799. {
  800. if (pImg == NULL) return FALSE;
  801. DWORD dwZoomPix;
  802. int retval = ZoomImg(SET_PIX(pImg->GetWidth(), pImg->GetHeight()), dwDisplayPix, dwZoomPix);
  803. if (retval == ZoomOut)
  804. {
  805. IMGkernelGlobal::WriteTextLog(_T("复制时放大图像,退出复制!"));
  806. return FALSE;
  807. }
  808. else if (retval == ZoomNull)
  809. {
  810. return SaveImg2newfile(pImg, strNewfile, uQuality);
  811. }
  812. // 绘制缩略图;
  813. Bitmap bitmap(GET_XPIX(dwZoomPix), GET_YPIX(dwZoomPix));
  814. Graphics *graphic = Graphics::FromImage(&bitmap);
  815. graphic->Clear(Color(255, 255, 255, 255));
  816. // 设置缩放或旋转图片时的算法(图片质量);
  817. graphic->SetInterpolationMode(InterpolationModeHighQualityBicubic);
  818. // 设置渲染图形对象的质量;
  819. graphic->SetSmoothingMode(SmoothingModeHighQuality);//SmoothingModeHighSpeed
  820. // 设置图形对象的像素偏移模式;
  821. graphic->SetPixelOffsetMode(PixelOffsetModeHighQuality);
  822. // 设置图形对象的合成模式;
  823. graphic->SetCompositingMode(CompositingModeSourceOver);
  824. // 设置图形对象的合成质量;
  825. graphic->SetCompositingQuality(CompositingQualityHighQuality);
  826. // 设置图形对象的文本渲染模式;
  827. graphic->SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
  828. graphic->DrawImage(pImg, 0, 0, GET_XPIX(dwZoomPix), GET_YPIX(dwZoomPix));
  829. delete graphic;
  830. // 生成缩略图;
  831. return SaveImg2newfile(&bitmap, strNewfile, uQuality);
  832. }
  833. BOOL IMGCommon::ImgThumbnail(IN LPCTSTR lpImgpath, IN CONST DWORD &dwDisplayPix, IN CString strNewfile, IN ULONG uQuality)
  834. {
  835. if (!PathFileExists(lpImgpath))
  836. return FALSE;
  837. #ifdef UNICODE
  838. Image Img(lpImgpath);
  839. #else
  840. BSTR strtmp = _bstr_t(lpImgpath);
  841. Image Img(strtmp);
  842. SysFreeString(strtmp);
  843. #endif
  844. DWORD dwZoomPix;
  845. int retval = ZoomImg(SET_PIX(Img.GetWidth(), Img.GetHeight()), dwDisplayPix, dwZoomPix);
  846. if (retval == ZoomOut)
  847. {
  848. IMGkernelGlobal::WriteTextLog(_T("复制时放大图像,退出复制!"));
  849. return FALSE;
  850. }
  851. else if (retval == ZoomNull)
  852. {
  853. return SaveImg2newfile(&Img, strNewfile, uQuality);
  854. }
  855. // 绘制缩略图;
  856. Bitmap bitmap(GET_XPIX(dwZoomPix), GET_YPIX(dwZoomPix));
  857. Graphics *graphic = Graphics::FromImage(&bitmap);
  858. graphic->Clear(Color(255, 255, 255, 255));
  859. // 设置缩放或旋转图片时的算法(图片质量);
  860. graphic->SetInterpolationMode(InterpolationModeHighQualityBicubic);
  861. // 设置渲染图形对象的质量;
  862. graphic->SetSmoothingMode(SmoothingModeHighQuality);//SmoothingModeHighSpeed
  863. // 设置图形对象的像素偏移模式;
  864. graphic->SetPixelOffsetMode(PixelOffsetModeHighQuality);
  865. // 设置图形对象的合成模式;
  866. graphic->SetCompositingMode(CompositingModeSourceOver);
  867. // 设置图形对象的合成质量;
  868. graphic->SetCompositingQuality(CompositingQualityHighQuality);
  869. // 设置图形对象的文本渲染模式;
  870. graphic->SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
  871. Status st = graphic->DrawImage(&Img, 0, 0, GET_XPIX(dwZoomPix), GET_YPIX(dwZoomPix));
  872. if ( st != Ok )
  873. {
  874. delete graphic;
  875. return FALSE;
  876. }
  877. delete graphic;
  878. // 生成缩略图;
  879. return SaveImg2newfile(&bitmap, strNewfile, uQuality);
  880. }
  881. BOOL IMGCommon::ImgThumbnail(IN CONST TString &strImgpath, IN CONST DWORD &dwDisplayPix, IN TString strNewfile, IN ULONG uQuality)
  882. {
  883. if (!PathFileExists(strImgpath.c_str()))
  884. {
  885. SetLastError(GetLastError());
  886. return FALSE;
  887. }
  888. #ifdef UNICODE
  889. BSTR strtmp = _bstr_t(strImgpath.c_str());
  890. Image Img(strtmp);
  891. SysFreeString(strtmp);
  892. //Image Img(strImgpath);
  893. #else
  894. BSTR strtmp = _bstr_t(strImgpath.c_str());
  895. Image Img(strtmp);
  896. SysFreeString(strtmp);
  897. #endif
  898. DWORD dwZoomPix;
  899. int retval = ZoomImg(SET_PIX(Img.GetWidth(), Img.GetHeight()), dwDisplayPix, dwZoomPix);
  900. if (retval == ZoomOut)
  901. {
  902. IMGkernelGlobal::WriteTextLog(_T("复制时放大图像,退出复制!"));
  903. return FALSE;
  904. }
  905. else if (retval == ZoomNull)
  906. {
  907. return SaveImg2newfile(&Img, strNewfile, uQuality);
  908. }
  909. // 绘制缩略图;
  910. Bitmap bitmap(GET_XPIX(dwZoomPix), GET_YPIX(dwZoomPix));
  911. Graphics *graphic = Graphics::FromImage(&bitmap);
  912. graphic->Clear(Color(255, 255, 255, 255));
  913. // 设置缩放或旋转图片时的算法(图片质量);
  914. graphic->SetInterpolationMode(InterpolationModeHighQualityBicubic);
  915. // 设置渲染图形对象的质量;
  916. graphic->SetSmoothingMode(SmoothingModeHighQuality);//SmoothingModeHighSpeed
  917. // 设置图形对象的像素偏移模式;
  918. graphic->SetPixelOffsetMode(PixelOffsetModeHighQuality);
  919. // 设置图形对象的合成模式;
  920. graphic->SetCompositingMode(CompositingModeSourceOver);
  921. // 设置图形对象的合成质量;
  922. graphic->SetCompositingQuality(CompositingQualityHighQuality);
  923. // 设置图形对象的文本渲染模式;
  924. graphic->SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
  925. Status st = graphic->DrawImage(&Img, 0, 0, GET_XPIX(dwZoomPix), GET_YPIX(dwZoomPix));
  926. if ( st != Ok )
  927. {
  928. delete graphic;
  929. return FALSE;
  930. }
  931. delete graphic;
  932. // 生成缩略图;
  933. return SaveImg2newfile(&bitmap, strNewfile, uQuality);
  934. }
  935. BOOL IMGCommon::SimpleImgThumbnail(IN LPCTSTR lpImgpath, IN CONST DWORD &dwDisplayPix, IN CString strNewfile, IN ULONG uQuality)
  936. {
  937. if (!PathFileExists(lpImgpath))
  938. return FALSE;
  939. DWORD dwZoomPix;
  940. Image *pImg = NULL;
  941. LoadImgFromFile(&pImg, lpImgpath);
  942. if ( pImg == NULL )
  943. {
  944. return FALSE;
  945. }
  946. int retval = ZoomImg(SET_PIX(pImg->GetWidth(), pImg->GetHeight()), dwDisplayPix, dwZoomPix);
  947. if (retval == ZoomOut)
  948. {
  949. IMGkernelGlobal::WriteTextLog(_T("复制时放大图像,退出复制!"));
  950. if (pImg) delete pImg;
  951. return FALSE;
  952. }
  953. else if (retval == ZoomNull)
  954. {
  955. BOOL bRet = SaveImg2newfile(pImg, strNewfile, uQuality);
  956. if (pImg) delete pImg;
  957. return bRet;
  958. }
  959. Image *pThumbnailImg = pImg->GetThumbnailImage(GET_XPIX(dwZoomPix), GET_YPIX(dwZoomPix));
  960. if (pThumbnailImg)
  961. {
  962. // 提高缩略图质量;
  963. Graphics graphic(pThumbnailImg);
  964. graphic.DrawImage(pImg, 0, 0, pThumbnailImg->GetWidth(), pThumbnailImg->GetHeight());
  965. INT nRientation = GetOrientation(pImg);
  966. if ( nRientation == 8 )
  967. {
  968. pThumbnailImg->RotateFlip(Rotate270FlipNone);
  969. }
  970. else if (nRientation == 6)
  971. {
  972. pThumbnailImg->RotateFlip(Rotate90FlipNone);
  973. }
  974. SaveImg2newfile(pThumbnailImg, strNewfile, uQuality);
  975. }
  976. else
  977. {
  978. if (pImg) delete pImg;
  979. return FALSE;
  980. }
  981. if (pImg) delete pImg;
  982. if (pThumbnailImg) delete pThumbnailImg;
  983. return TRUE;
  984. }
  985. void IMGCommon::CopyWithExt(IN CONST TString& strfile, IN TString& strChange, IN STR_VEC& vtExts, IN BOOL bFailIfExists)
  986. {
  987. // 复制其他扩展名的相片;
  988. INT nIndex = 0;
  989. for (STR_VEC::iterator it = vtExts.begin(); it != vtExts.end(); it++)
  990. {
  991. TString strWithExt = IMGkernelGlobal::lowercase(strfile.c_str());
  992. if (strWithExt.find(it->c_str()) != TString::npos) // 不复制本扩展名;
  993. continue;
  994. nIndex = strfile.find_last_of(_T('.'));
  995. if (nIndex != TString::npos)
  996. {
  997. //strWithExt.replace(nIndex,itExt->size(),itExt->c_str());
  998. //strtmp.replace(strtmp.find_last_of(_T('.')), itExt->size(), itExt->c_str());
  999. strWithExt.replace(nIndex, strfile.length() - nIndex, it->c_str());
  1000. nIndex = strChange.find_last_of(_T('.'));
  1001. if ( nIndex != TString::npos )
  1002. {
  1003. strChange.replace(nIndex, strChange.length() - nIndex, it->c_str());
  1004. if (!PathFileExists(strWithExt.c_str()))
  1005. continue;
  1006. if (!CopyFile(strWithExt.c_str(), strChange.c_str(), bFailIfExists))
  1007. {
  1008. // 返回复制错误信息;
  1009. //m_richlog.SetSel(-1, -1);
  1010. //m_richlog.ReplaceSel( _T("复制相片时出错\r") );
  1011. }
  1012. }
  1013. }
  1014. }
  1015. }
  1016. BOOL IMGCommon::CopyFileEx(IN TString& strExistFile, IN OUT TString& strNewFile, IN CONST DWORD& dwZoomPix, IN CONST INT& nCopyType)
  1017. {
  1018. if ( nCopyType == COPY_FAIL_IF_EXISTS )
  1019. {// 文件存在,不覆盖;
  1020. if ( PathFileExists(strNewFile.c_str()) )
  1021. return TRUE;
  1022. }
  1023. else if ( nCopyType == COPY_OTHER_NAME_IF_EXISTS )
  1024. {// 文件存在,重命名;
  1025. TCHAR szNewFileName[_MAX_PATH] = { 0 };
  1026. TCHAR szDrive[_MAX_DRIVE] = { 0 };
  1027. TCHAR szDir[_MAX_DIR] = { 0 };
  1028. TCHAR szFna[_MAX_FNAME] = { 0 };
  1029. TCHAR szExt[_MAX_EXT] = { 0 };
  1030. StringCchPrintf(szNewFileName, _MAX_PATH, _T("%s"), strNewFile.c_str());
  1031. _tsplitpath_s(szNewFileName, szDrive, szDir, szFna, szExt);
  1032. int nIndex = 1;
  1033. //判断指定文件夹下某个文件是否存在
  1034. while (PathFileExists(szNewFileName))
  1035. {
  1036. // 当副本很多时,这里会很慢,如 "001 (100).jpg",那么就要循环100次才生成"001 (101).jpg";
  1037. StringCchPrintf(szNewFileName, _MAX_PATH, _T("%s%s%s (%d)%s"), szDrive, szDir, szFna, nIndex++, szExt);
  1038. }
  1039. // 赋值返回;
  1040. strNewFile = szNewFileName;
  1041. }
  1042. // 默认文件存在,直接覆盖;
  1043. if ( PathFileExists(strNewFile.substr(0, strNewFile.find_last_of(_T('\\'))).c_str()) == FALSE )
  1044. {
  1045. SHCreateDirectoryEx(NULL, strNewFile.substr(0, strNewFile.find_last_of(_T('\\'))).c_str(), NULL);
  1046. }
  1047. return ImgThumbnail(strExistFile.c_str(), dwZoomPix, strNewFile.c_str(), 100);
  1048. }
  1049. TString IMGCommon::CopyImage( IN TString &strSourceImg, IN LPCTSTR lpDestDirectory, IN CONST DWORD& dwZoomPix, IN CONST INT& nCopyType, IN CString strPerImgGoods, IN BOOL bGoodsWithName, IN LPCTSTR lpSeparator, IN BOOL bKeepbackWard, IN CONST INT &nLayers )
  1050. {
  1051. // 判断源文件是否存在;
  1052. if ( !PathFileExists(strSourceImg.c_str()) || !lpDestDirectory )
  1053. {
  1054. IMGkernelGlobal::WriteTextLog(_T("%s-%s:参数无效"), __FILE__, __FUNCTION__);
  1055. // 如果可以,使用SetLastError设置自定义的错误码和描述符;再通过GetLastError返回自定义的结果;
  1056. return _T("");
  1057. }
  1058. if ( !PathFileExists(lpDestDirectory) )
  1059. {// 目标路径不存在,创建;
  1060. INT nRet = SHCreateDirectoryEx(NULL, lpDestDirectory, NULL);
  1061. if ( ERROR_SUCCESS != nRet && ERROR_ALREADY_EXISTS != nRet)
  1062. {
  1063. IMGkernelGlobal::WriteTextLog(_T("创建目录失败,请确认是否有权限或路径名有效"));
  1064. return _T("");
  1065. }
  1066. }
  1067. // 分隔出需要的文件夹层(即需要套系文件夹名或景点名);
  1068. INT nIndex = 0;
  1069. TString strSeparator;
  1070. TString strNewImg = lpDestDirectory;
  1071. if ( strNewImg[strNewImg.size() - 1] == _T('\\') )
  1072. {
  1073. strNewImg = strNewImg.substr(0, strNewImg.size() - 1);
  1074. }
  1075. //////////////////////////////////////////////////////////////////////////
  1076. if ( lpSeparator == NULL )
  1077. {
  1078. nIndex = strSourceImg.find_last_of(_T('\\'));
  1079. if ( nIndex == TString::npos )
  1080. {
  1081. IMGkernelGlobal::WriteTextLog(_T("未找到分层符"));
  1082. return _T("");
  1083. }
  1084. strSeparator = strSourceImg.substr(nIndex);
  1085. }
  1086. else
  1087. {
  1088. strSeparator = lpSeparator;
  1089. strSeparator = IMGkernelGlobal::lowercase(strSeparator);
  1090. nIndex = strSourceImg.find(strSeparator);
  1091. if ( nIndex == TString::npos )
  1092. {
  1093. IMGkernelGlobal::WriteTextLog(_T("未找到该分隔符"));
  1094. return _T("");
  1095. }
  1096. if ( bKeepbackWard )
  1097. {// 向后保留;
  1098. strSeparator = strSourceImg.substr(nIndex + _tcslen(lpSeparator));
  1099. if ( strSeparator[0] != _T('\\') )
  1100. {// 如果截断后,还属于上层文件夹,继续截断;
  1101. nIndex = strSeparator.find_first_of(_T('\\'));
  1102. if ( nIndex != TString::npos )
  1103. {
  1104. strSeparator = strSeparator.substr(nIndex+1);
  1105. }
  1106. else
  1107. {// 如果没有找到文件夹分层符,返回空;
  1108. IMGkernelGlobal::WriteTextLog(_T("无法找到文件夹分层符"));
  1109. return _T("");
  1110. }
  1111. }
  1112. else
  1113. {
  1114. strSeparator = strSeparator.substr(1);
  1115. }
  1116. // 按层截取指定的文件夹名称;
  1117. INT nCurLayer = nLayers;
  1118. if ( nCurLayer != 0 )
  1119. {
  1120. do{
  1121. nIndex = strSeparator.find_first_of(_T('\\'));
  1122. if ( nIndex != TString::npos )
  1123. {
  1124. strNewImg.append(_T("\\"));
  1125. strNewImg.append(strSeparator.substr(0,nIndex));
  1126. strSeparator = strSeparator.substr(nIndex+1);
  1127. nCurLayer--;
  1128. }
  1129. else
  1130. {
  1131. break;
  1132. }
  1133. }while(nCurLayer);
  1134. }
  1135. if( nCurLayer != 0 )
  1136. {// 不等于0,没找到相应的层;
  1137. IMGkernelGlobal::WriteTextLog(_T("没有找到相应层数文件夹"));
  1138. return _T("");
  1139. }
  1140. else
  1141. {
  1142. nIndex = strSeparator.find_last_of(_T('\\'));
  1143. if ( nIndex != TString::npos )
  1144. {
  1145. strSeparator = strSeparator.substr(nIndex);
  1146. }
  1147. #if 0
  1148. nIndex = strSeparator.find_last_of(_T('.'));
  1149. if ( nIndex != TString::npos )
  1150. {
  1151. strNewImg.append(_T("\\"));
  1152. strNewImg.append(strSeparator.substr(0,nIndex));
  1153. // 扩展名;
  1154. strSeparator = strSeparator.substr(nIndex);
  1155. }
  1156. #endif
  1157. }
  1158. }
  1159. else
  1160. {// 向前保留;
  1161. strSeparator = strSourceImg.substr(0, nIndex);
  1162. if ( strSeparator[strSeparator.size() - 1] != _T('\\') )
  1163. {
  1164. nIndex = strSeparator.find_last_of(_T('\\'));
  1165. if ( nIndex != TString::npos )
  1166. {
  1167. strSeparator = strSeparator.substr(0, nIndex);
  1168. }
  1169. else
  1170. {// 如果没有找到文件夹分层符,返回空;
  1171. IMGkernelGlobal::WriteTextLog(_T("无法找到文件夹分层符"));
  1172. return _T("");
  1173. }
  1174. }
  1175. else
  1176. {
  1177. strSeparator = strSourceImg.substr(0,strSeparator.size()-1);
  1178. }
  1179. // 按层截取指定的文件夹名称;
  1180. INT nCurLayer = nLayers;
  1181. if ( nCurLayer != 0 )
  1182. {
  1183. do{
  1184. nIndex = strSeparator.find_last_of(_T('\\'));
  1185. if ( nIndex != TString::npos )
  1186. {
  1187. strNewImg.append(strSeparator.substr(nIndex));
  1188. strSeparator = strSeparator.substr(0,nIndex);
  1189. nCurLayer--;
  1190. }
  1191. else
  1192. {
  1193. break;
  1194. }
  1195. }while(nCurLayer);
  1196. }
  1197. if ( nCurLayer != 0 )
  1198. {// 不等于0,没找到相应的层;
  1199. IMGkernelGlobal::WriteTextLog(_T("没有找到相应层数文件夹"));
  1200. return _T("");
  1201. }
  1202. else
  1203. {
  1204. nIndex = strSourceImg.find_last_of(_T('\\'));
  1205. if ( nIndex != TString::npos )
  1206. {
  1207. strSeparator = strSourceImg.substr(nIndex+1);
  1208. #if 0
  1209. nIndex = strSeparator.find_last_of(_T('.'));
  1210. if ( nIndex != TString::npos )
  1211. {
  1212. strNewImg.append(_T("\\"));
  1213. strNewImg.append(strSeparator.substr(0,nIndex));
  1214. // 扩展名;
  1215. strSeparator = strSeparator.substr(nIndex);
  1216. }
  1217. #endif
  1218. }
  1219. }
  1220. }
  1221. }
  1222. //////////////////////////////////////////////////////////////////////////
  1223. // strNewImg + [] + strSeparator = 新文件名;
  1224. // 处理strPerImgGoods与新文件名的合并;
  1225. if ( bGoodsWithName )
  1226. {
  1227. nIndex = strSeparator.find_last_of(_T('.'));
  1228. if ( nIndex != TString::npos )
  1229. {
  1230. strNewImg.append(_T("\\"));
  1231. strNewImg.append(strSeparator.substr(0,nIndex));
  1232. // 扩展名;
  1233. strSeparator = strSeparator.substr(nIndex);
  1234. }
  1235. strNewImg.append(_T("("));
  1236. strNewImg.append(strPerImgGoods.GetString());
  1237. strNewImg.append(_T(")"));
  1238. strNewImg.append(strSeparator);
  1239. if ( dwZoomPix == INVALID_COPY_PIX )
  1240. {
  1241. if ( !IMGkernelGlobal::CopyFileEx(strSourceImg, strNewImg, nCopyType) )
  1242. {
  1243. IMGkernelGlobal::WriteTextLog(_T("复制时出错"));
  1244. return _T("");
  1245. }
  1246. }
  1247. else
  1248. {
  1249. if ( !CopyFileEx(strSourceImg, strNewImg, dwZoomPix, nCopyType) )
  1250. {
  1251. IMGkernelGlobal::WriteTextLog(_T("复制时出错"));
  1252. return _T("");
  1253. }
  1254. }
  1255. }
  1256. else
  1257. {// 分目录;
  1258. CString strGoods;
  1259. TString strtemp;
  1260. strPerImgGoods += _T(";");
  1261. do
  1262. {
  1263. nIndex = strPerImgGoods.Find(_T(";"));
  1264. if ( nIndex != -1 )
  1265. {
  1266. strGoods = strPerImgGoods.Left(nIndex);
  1267. strPerImgGoods = strPerImgGoods.Mid(nIndex+1);
  1268. strtemp = strNewImg;
  1269. strtemp.append(_T("\\"));
  1270. strtemp.append(strGoods.GetString());
  1271. nIndex = strSeparator.find_last_of(_T('.'));
  1272. if ( nIndex != TString::npos )
  1273. {
  1274. strtemp.append(_T("\\"));
  1275. strtemp.append(strSeparator.substr(0,nIndex));
  1276. }
  1277. strtemp.append(strSeparator.substr(nIndex));
  1278. if ( dwZoomPix == INVALID_COPY_PIX )
  1279. {
  1280. if ( !IMGkernelGlobal::CopyFileEx(strSourceImg, strtemp, nCopyType) )
  1281. {
  1282. IMGkernelGlobal::WriteTextLog(_T("复制文件时出错"));
  1283. continue;
  1284. }
  1285. }
  1286. else
  1287. {
  1288. if ( !CopyFileEx(strSourceImg, strtemp, dwZoomPix, nCopyType))
  1289. {
  1290. IMGkernelGlobal::WriteTextLog(_T("复制文件时出错"));
  1291. continue;
  1292. }
  1293. }
  1294. }
  1295. } while ( strPerImgGoods.Find(_T(";")) != -1 );
  1296. }
  1297. return strNewImg;
  1298. }
  1299. /************************************************************************/
  1300. /* 函数:CopyImageEx[3/6/2016 IT];
  1301. /* 描述:;
  1302. /* 参数:;
  1303. /* [IN] :;
  1304. /* [OUT] :;
  1305. /* [IN/OUT] :;
  1306. /* 返回:void;
  1307. /* 注意:;
  1308. /* 示例:;
  1309. /*
  1310. /* 修改:;
  1311. /* 日期:;
  1312. /* 内容:;
  1313. /************************************************************************/
  1314. BOOL IMGCommon::CopyImageEx(
  1315. IN TString &strSourceImg,
  1316. IN LPCTSTR lpDestDirectory,
  1317. IN CONST DWORD& dwZoomPix,
  1318. IN CONST INT& nCopyType,
  1319. IN STR_VEC& vtWithExt,
  1320. IN CString strPerImgGoods,
  1321. IN BOOL bGoodsWithName,
  1322. IN LPCTSTR lpCustomInfo,
  1323. IN LPCTSTR lpSeparator,
  1324. IN BOOL bKeepbackWard,
  1325. IN CONST INT &nLayers )
  1326. {
  1327. // 判断源文件是否存在;
  1328. if ( !PathFileExists(strSourceImg.c_str()) || !lpDestDirectory || strPerImgGoods.IsEmpty())
  1329. {
  1330. IMGkernelGlobal::WriteTextLog(_T("%s-%s:参数无效"), __FILE__, __FUNCTION__);
  1331. // 如果可以,使用SetLastError设置自定义的错误码和描述符;再通过GetLastError返回自定义的结果;
  1332. return FALSE;
  1333. }
  1334. if ( !PathFileExists(lpDestDirectory) )
  1335. {// 目标路径不存在,创建;
  1336. INT nRet = SHCreateDirectoryEx(NULL, lpDestDirectory, NULL) ;
  1337. if ( ERROR_SUCCESS != nRet && ERROR_ALREADY_EXISTS != nRet )
  1338. {
  1339. IMGkernelGlobal::WriteTextLog(_T("创建目录失败,请确认是否有权限或路径名有效"));
  1340. return FALSE;
  1341. }
  1342. }
  1343. // 分隔出需要的文件夹层(即需要套系文件夹名或景点名);
  1344. INT nIndex = 0;
  1345. TString strSeparator;
  1346. TString strNewImg = lpDestDirectory;
  1347. if ( strNewImg[strNewImg.size() - 1] == _T('\\') )
  1348. {
  1349. strNewImg = strNewImg.substr(0, strNewImg.size() - 1);
  1350. }
  1351. //////////////////////////////////////////////////////////////////////////
  1352. if ( lpSeparator == NULL )
  1353. {
  1354. #ifdef _THE_TEST_
  1355. IMGkernelGlobal::WriteTextLog(_T("分隔符为空~"));
  1356. #endif
  1357. nIndex = strSourceImg.find_last_of(_T('\\'));
  1358. if ( nIndex == TString::npos )
  1359. {
  1360. IMGkernelGlobal::WriteTextLog(_T("未找到分层符"));
  1361. return FALSE;
  1362. }
  1363. strSeparator = strSourceImg.substr(nIndex);
  1364. }
  1365. else
  1366. {
  1367. #ifdef _THE_TEST_
  1368. IMGkernelGlobal::WriteTextLog(_T("分隔符:"));
  1369. IMGkernelGlobal::WriteTextLog(lpSeparator);
  1370. if (nLayers == 1)
  1371. IMGkernelGlobal::WriteTextLog(_T("1层"));
  1372. else
  1373. IMGkernelGlobal::WriteTextLog(_T("0层"));
  1374. #endif
  1375. strSeparator = lpSeparator;
  1376. strSeparator = IMGkernelGlobal::lowercase(strSeparator);
  1377. nIndex = strSourceImg.find(strSeparator);
  1378. if ( nIndex == TString::npos )
  1379. {
  1380. IMGkernelGlobal::WriteTextLog(_T("未找到该分隔符"));
  1381. return FALSE;
  1382. }
  1383. if ( bKeepbackWard )
  1384. {// 向后保留;
  1385. strSeparator = strSourceImg.substr(nIndex + _tcslen(lpSeparator));
  1386. #if _THE_TEST_
  1387. IMGkernelGlobal::WriteTextLog(_T("向后保留:"));
  1388. IMGkernelGlobal::WriteTextLog(strSeparator.c_str());
  1389. #endif
  1390. if ( strSeparator[0] != _T('\\') )
  1391. {// 如果截断后,还属于上层文件夹,继续截断;
  1392. nIndex = strSeparator.find_first_of(_T('\\'));
  1393. if ( nIndex != TString::npos )
  1394. {
  1395. strSeparator = strSeparator.substr(nIndex+1);
  1396. }
  1397. else
  1398. {// 如果没有找到文件夹分层符,返回空;
  1399. IMGkernelGlobal::WriteTextLog(_T("无法找到文件夹分层符"));
  1400. return FALSE;
  1401. }
  1402. }
  1403. else
  1404. {
  1405. strSeparator = strSeparator.substr(1);
  1406. }
  1407. // 按层截取指定的文件夹名称;
  1408. INT nCurLayer = nLayers;
  1409. if ( nCurLayer != 0 )
  1410. {
  1411. if (nCurLayer == -1 ) nCurLayer = 65536;
  1412. do{
  1413. nIndex = strSeparator.find_first_of(_T('\\'));
  1414. if ( nIndex != TString::npos )
  1415. {
  1416. strNewImg.append(_T("\\"));
  1417. strNewImg.append(strSeparator.substr(0,nIndex));
  1418. strSeparator = strSeparator.substr(nIndex+1);
  1419. nCurLayer--;
  1420. }
  1421. else
  1422. {
  1423. if ( nLayers == 1 )
  1424. nCurLayer--;
  1425. break;
  1426. }
  1427. }while(nCurLayer);
  1428. }
  1429. if( nCurLayer != 0 )
  1430. {// 不等于0,没找到相应的层;
  1431. #ifdef _THE_TEST_
  1432. IMGkernelGlobal::WriteTextLog(_T("分隔符=:"));
  1433. IMGkernelGlobal::WriteTextLog(strSeparator.c_str());
  1434. IMGkernelGlobal::WriteTextLog(strNewImg.c_str());
  1435. #endif
  1436. IMGkernelGlobal::WriteTextLog(_T("没有找到相应层数文件夹.1."));
  1437. return FALSE;
  1438. }
  1439. else
  1440. {
  1441. nIndex = strSeparator.find_last_of(_T('\\'));
  1442. if ( nIndex != TString::npos )
  1443. {
  1444. strSeparator = strSeparator.substr(nIndex);
  1445. }
  1446. }
  1447. }
  1448. else
  1449. {// 向前保留;
  1450. strSeparator = strSourceImg.substr(0, nIndex);
  1451. if ( strSeparator[strSeparator.size() - 1] != _T('\\') )
  1452. {
  1453. nIndex = strSeparator.find_last_of(_T('\\'));
  1454. if ( nIndex != TString::npos )
  1455. {
  1456. strSeparator = strSeparator.substr(0, nIndex);
  1457. }
  1458. else
  1459. {// 如果没有找到文件夹分层符,返回空;
  1460. IMGkernelGlobal::WriteTextLog(_T("无法找到文件夹分层符.2."));
  1461. return FALSE;
  1462. }
  1463. }
  1464. else
  1465. {
  1466. strSeparator = strSourceImg.substr(0,strSeparator.size()-1);
  1467. }
  1468. // 按层截取指定的文件夹名称;
  1469. INT nCurLayer = nLayers;
  1470. if ( nCurLayer != 0 )
  1471. {
  1472. do{
  1473. nIndex = strSeparator.find_last_of(_T('\\'));
  1474. if ( nIndex != TString::npos )
  1475. {
  1476. strNewImg.append(strSeparator.substr(nIndex));
  1477. strSeparator = strSeparator.substr(0,nIndex);
  1478. nCurLayer--;
  1479. }
  1480. else
  1481. {
  1482. break;
  1483. }
  1484. }while(nCurLayer);
  1485. }
  1486. if ( nCurLayer != 0 )
  1487. {// 不等于0,没找到相应的层;
  1488. IMGkernelGlobal::WriteTextLog(_T("没有找到相应层数文件夹.3."));
  1489. return FALSE;
  1490. }
  1491. else
  1492. {
  1493. nIndex = strSourceImg.find_last_of(_T('\\'));
  1494. if ( nIndex != TString::npos )
  1495. {
  1496. strSeparator = strSourceImg.substr(nIndex+1);
  1497. }
  1498. }
  1499. }
  1500. }
  1501. //////////////////////////////////////////////////////////////////////////
  1502. // strNewImg + [] + strSeparator = 新文件名;
  1503. // 处理strPerImgGoods与新文件名的合并;
  1504. if ( bGoodsWithName )
  1505. {
  1506. nIndex = strSeparator.find_last_of(_T('.'));
  1507. if ( nIndex != TString::npos )
  1508. {
  1509. strNewImg.append(_T("\\"));
  1510. strNewImg.append(strSeparator.substr(0,nIndex));
  1511. // 扩展名;
  1512. strSeparator = strSeparator.substr(nIndex);
  1513. }
  1514. strNewImg.append(_T("("));
  1515. if ( lpCustomInfo && lpCustomInfo[0] != _T('\0') )
  1516. {
  1517. strNewImg.append(lpCustomInfo);
  1518. strNewImg.append(_T(","));
  1519. }
  1520. strNewImg.append(strPerImgGoods.GetString());
  1521. strNewImg.append(_T(")"));
  1522. strNewImg.append(strSeparator);
  1523. if ( dwZoomPix == INVALID_COPY_PIX )
  1524. {
  1525. if ( !IMGkernelGlobal::CopyFileEx(strSourceImg, strNewImg, nCopyType) )
  1526. {
  1527. IMGkernelGlobal::WriteTextLog(_T("复制时出错"));
  1528. return FALSE;
  1529. }
  1530. CopyWithExt(strSourceImg, strNewImg, vtWithExt, FALSE);
  1531. }
  1532. else
  1533. {
  1534. if ( !CopyFileEx(strSourceImg, strNewImg, dwZoomPix, nCopyType) )
  1535. {
  1536. IMGkernelGlobal::WriteTextLog(_T("复制时出错"));
  1537. return FALSE;
  1538. }
  1539. CopyWithExt(strSourceImg, strNewImg, vtWithExt, FALSE);
  1540. }
  1541. }
  1542. else
  1543. {// 分目录;
  1544. CString strGoods;
  1545. TString strtemp;
  1546. strPerImgGoods += _T(";");
  1547. do
  1548. {
  1549. nIndex = strPerImgGoods.Find(_T(";"));
  1550. if ( nIndex != -1 )
  1551. {
  1552. strGoods = strPerImgGoods.Left(nIndex);
  1553. strPerImgGoods = strPerImgGoods.Mid(nIndex+1);
  1554. strtemp = strNewImg;
  1555. strtemp.append(_T("\\"));
  1556. strtemp.append(strGoods.GetString());
  1557. nIndex = strSeparator.find_last_of(_T('.'));
  1558. if ( nIndex != TString::npos )
  1559. {
  1560. strtemp.append(_T("\\"));
  1561. strtemp.append(strSeparator.substr(0,nIndex));
  1562. }
  1563. strtemp.append(strSeparator.substr(nIndex));
  1564. if ( dwZoomPix == INVALID_COPY_PIX )
  1565. {
  1566. if ( !IMGkernelGlobal::CopyFileEx(strSourceImg, strtemp, nCopyType) )
  1567. {
  1568. IMGkernelGlobal::WriteTextLog(_T("复制文件时出错"));
  1569. continue;
  1570. }
  1571. CopyWithExt(strSourceImg, strtemp, vtWithExt, FALSE);
  1572. }
  1573. else
  1574. {
  1575. if ( !CopyFileEx(strSourceImg, strtemp, dwZoomPix, nCopyType))
  1576. {
  1577. IMGkernelGlobal::WriteTextLog(_T("复制文件时出错"));
  1578. continue;
  1579. }
  1580. CopyWithExt(strSourceImg, strtemp, vtWithExt, FALSE);
  1581. }
  1582. }
  1583. } while ( strPerImgGoods.Find(_T(";")) != -1 );
  1584. }
  1585. return TRUE;
  1586. }
  1587. /************************************************************************/
  1588. /*
  1589. 函数:ExportCropImageToFile
  1590. 描述:导出裁剪相片;
  1591. 参数:
  1592. strSourceImg
  1593. 源相片文件路径;
  1594. strSaveDirectory
  1595. 保存裁剪后的文件目录;
  1596. nExportType
  1597. 裁剪的操作类型;
  1598. strCropInfo
  1599. 裁剪信息(保存在[dindan].[size]字段中,
  1600. 格式如:"225:5X7,1440,900,88,0,1352,900;",
  1601. 内容如:相片名|裁剪方案|原片宽|原片高|裁剪left|裁剪top|裁剪bottom|裁剪rigth);
  1602. lpSeparator
  1603. 截取strSourceImg的分隔符;
  1604. bKeepbackWard
  1605. TRUE向后截取分隔符字符串,FALSE向前截取分隔符字符串;
  1606. nLayers
  1607. 返回:
  1608. 注意:
  1609. 示例:
  1610. */
  1611. /************************************************************************/
  1612. BOOL IMGCommon::ExportCropImageToFile(IN CONST TString& strSourceImg, IN LPCTSTR lpSaveDirectory, IN CONST INT& nExportType, IN CString strCropInfo, IN LPCTSTR lpSeparator, IN BOOL bKeepbackWard, IN CONST INT &nLayers)
  1613. {
  1614. // 判断参数有效性;
  1615. if ( !PathFileExists(strSourceImg.c_str()) )
  1616. {
  1617. IMGkernelGlobal::WriteTextLog(_T("源相片文件无效"));
  1618. return FALSE;
  1619. }
  1620. if ( !PathFileExists(lpSaveDirectory) )
  1621. {
  1622. INT nRet = SHCreateDirectoryEx(NULL, lpSaveDirectory, NULL);
  1623. if ( ERROR_SUCCESS != nRet && ERROR_ALREADY_EXISTS != nRet )
  1624. {
  1625. IMGkernelGlobal::WriteTextLog(_T("生成目录失败"));
  1626. return FALSE;
  1627. }
  1628. }
  1629. // 分隔出需要的文件夹层(即需要套系文件夹名或景点名);
  1630. INT nIndex = 0;
  1631. TString strSeparator;
  1632. TString strNewImg = lpSaveDirectory;
  1633. if ( strNewImg[strNewImg.size() - 1] == _T('\\') )
  1634. {
  1635. strNewImg = strNewImg.substr(0, strNewImg.size() - 1);
  1636. }
  1637. //////////////////////////////////////////////////////////////////////////
  1638. if ( lpSeparator == NULL )
  1639. {
  1640. nIndex = strSourceImg.find_last_of(_T('\\'));
  1641. if ( nIndex == TString::npos )
  1642. {
  1643. IMGkernelGlobal::WriteTextLog(_T("未找到分层符"));
  1644. return FALSE;
  1645. }
  1646. strSeparator = strSourceImg.substr(nIndex);
  1647. }
  1648. else
  1649. {
  1650. strSeparator = lpSeparator;
  1651. strSeparator = IMGkernelGlobal::lowercase(strSeparator);
  1652. nIndex = strSourceImg.find(strSeparator);
  1653. if ( nIndex == TString::npos )
  1654. {
  1655. IMGkernelGlobal::WriteTextLog(_T("未找到该分隔符"));
  1656. return FALSE;
  1657. }
  1658. if ( bKeepbackWard )
  1659. {// 向后保留;
  1660. strSeparator = strSourceImg.substr(nIndex + _tcslen(lpSeparator));
  1661. if ( strSeparator[0] != _T('\\') )
  1662. {// 如果截断后,还属于上层文件夹,继续截断;
  1663. nIndex = strSeparator.find_first_of(_T('\\'));
  1664. if ( nIndex != TString::npos )
  1665. {
  1666. strSeparator = strSeparator.substr(nIndex+1);
  1667. }
  1668. else
  1669. {// 如果没有找到文件夹分层符,返回空;
  1670. IMGkernelGlobal::WriteTextLog(_T("无法找到文件夹分层符"));
  1671. return FALSE;
  1672. }
  1673. }
  1674. else
  1675. {
  1676. strSeparator = strSeparator.substr(1);
  1677. }
  1678. // 按层截取指定的文件夹名称;
  1679. INT nCurLayer = nLayers;
  1680. if ( nCurLayer != 0 )
  1681. {
  1682. do{
  1683. nIndex = strSeparator.find_first_of(_T('\\'));
  1684. if ( nIndex != TString::npos )
  1685. {
  1686. strNewImg.append(_T("\\"));
  1687. strNewImg.append(strSeparator.substr(0,nIndex));
  1688. strSeparator = strSeparator.substr(nIndex+1);
  1689. nCurLayer--;
  1690. }
  1691. else
  1692. {
  1693. break;
  1694. }
  1695. }while(nCurLayer);
  1696. }
  1697. if( nCurLayer != 0 )
  1698. {// 不等于0,没找到相应的层;
  1699. IMGkernelGlobal::WriteTextLog(_T("没有找到相应层数文件夹"));
  1700. return FALSE;
  1701. }
  1702. else
  1703. {
  1704. nIndex = strSeparator.find_last_of(_T('\\'));
  1705. if ( nIndex != TString::npos )
  1706. {
  1707. strSeparator = strSeparator.substr(nIndex);
  1708. }
  1709. }
  1710. }
  1711. else
  1712. {// 向前保留;
  1713. strSeparator = strSourceImg.substr(0, nIndex);
  1714. if ( strSeparator[strSeparator.size() - 1] != _T('\\') )
  1715. {
  1716. nIndex = strSeparator.find_last_of(_T('\\'));
  1717. if ( nIndex != TString::npos )
  1718. {
  1719. strSeparator = strSeparator.substr(0, nIndex);
  1720. }
  1721. else
  1722. {// 如果没有找到文件夹分层符,返回空;
  1723. IMGkernelGlobal::WriteTextLog(_T("无法找到文件夹分层符"));
  1724. return FALSE;
  1725. }
  1726. }
  1727. else
  1728. {
  1729. strSeparator = strSourceImg.substr(0,strSeparator.size()-1);
  1730. }
  1731. // 按层截取指定的文件夹名称;
  1732. INT nCurLayer = nLayers;
  1733. if ( nCurLayer != 0 )
  1734. {
  1735. do{
  1736. nIndex = strSeparator.find_last_of(_T('\\'));
  1737. if ( nIndex != TString::npos )
  1738. {
  1739. strNewImg.append(strSeparator.substr(nIndex));
  1740. strSeparator = strSeparator.substr(0,nIndex);
  1741. nCurLayer--;
  1742. }
  1743. else
  1744. {
  1745. break;
  1746. }
  1747. }while(nCurLayer);
  1748. }
  1749. if ( nCurLayer != 0 )
  1750. {// 不等于0,没找到相应的层;
  1751. IMGkernelGlobal::WriteTextLog(_T("没有找到相应层数文件夹"));
  1752. return FALSE;
  1753. }
  1754. else
  1755. {
  1756. nIndex = strSourceImg.find_last_of(_T('\\'));
  1757. if ( nIndex != TString::npos )
  1758. {
  1759. strSeparator = strSourceImg.substr(nIndex+1);
  1760. }
  1761. }
  1762. }
  1763. }
  1764. // 获取与源同名的裁剪信息;
  1765. TString strName = IMGkernelGlobal::getfilename(strSourceImg);
  1766. if ( strName.size() == 0 )
  1767. {
  1768. IMGkernelGlobal::WriteTextLog(_T("获取文件名错误"));
  1769. return FALSE;
  1770. }
  1771. CString strTemp = _T("");
  1772. do
  1773. {
  1774. // 225:5X7,1440,900,88,0,1352,900;
  1775. nIndex = strCropInfo.Find(_T(';'));
  1776. if ( nIndex != -1 )
  1777. {
  1778. strTemp = strCropInfo.Left(nIndex);
  1779. strCropInfo = strCropInfo.Mid(nIndex + 1);
  1780. nIndex = strTemp.Find(_T(':'));
  1781. if ( nIndex != -1 )
  1782. {
  1783. if ( strTemp.Left(nIndex).CompareNoCase(strName.c_str()) == 0 )
  1784. {// 获取同名裁剪信息;
  1785. AnalysisCropInfo(strName, strSourceImg, strNewImg.c_str(), strTemp);
  1786. }
  1787. }
  1788. }
  1789. } while (nIndex != -1);
  1790. return TRUE;
  1791. }
  1792. BOOL IMGCommon::AnalysisCropInfo(IN TString &strName, IN CONST TString& strSourceImg, IN LPCTSTR lpSaveDirectory, IN CString strCropInfo)
  1793. {
  1794. CRect rcCrop;
  1795. INT nIndex = 0;
  1796. CString strCropScheme = _T("");
  1797. nIndex = strCropInfo.Find(_T(','));
  1798. strCropScheme = strCropInfo.Left(nIndex); // 裁剪方案;
  1799. strCropInfo.Delete(0, nIndex + 1);
  1800. // 裁剪方案;
  1801. nIndex = strCropScheme.Find(_T(":"));
  1802. if ( nIndex != -1 )
  1803. {
  1804. strCropScheme = strCropScheme.Mid(nIndex+1);
  1805. }
  1806. // 裁剪缩放显示时的相片宽;
  1807. nIndex = strCropInfo.Find(_T(','));
  1808. LONG SrcImageWid = _ttol(strCropInfo.Left(nIndex));
  1809. strCropInfo.Delete(0, nIndex + 1);
  1810. // 裁剪缩放显示时的相片高;
  1811. nIndex = strCropInfo.Find(_T(','));
  1812. LONG SrcImageHei = _ttol(strCropInfo.Left(nIndex));
  1813. strCropInfo.Delete(0, nIndex + 1);
  1814. // 缩略显示时被裁剪的left坐标值;
  1815. nIndex = strCropInfo.Find(_T(','));
  1816. rcCrop.left = _ttol(strCropInfo.Left(nIndex));
  1817. strCropInfo.Delete(0, nIndex + 1);
  1818. // 缩略显示时被裁剪的top坐标值;
  1819. nIndex = strCropInfo.Find(_T(','));
  1820. rcCrop.top = _ttol(strCropInfo.Left(nIndex));
  1821. strCropInfo.Delete(0, nIndex + 1);
  1822. // 缩略显示时被裁剪的right坐标值;
  1823. nIndex = strCropInfo.Find(_T(','));
  1824. rcCrop.right = _ttol(strCropInfo.Left(nIndex));
  1825. strCropInfo.Delete(0, nIndex + 1);
  1826. // 缩略显示时被裁剪的bottom坐标值;
  1827. rcCrop.bottom = _ttol(strCropInfo);
  1828. Image *pImgCrop = NULL;
  1829. if ( !LoadImgFromBuffer(&pImgCrop, strSourceImg.c_str()) || pImgCrop == NULL )
  1830. {
  1831. IMGkernelGlobal::WriteTextLog(_T("加载相片失败"));
  1832. return FALSE;
  1833. }
  1834. if ( pImgCrop->GetWidth() == 0 )
  1835. {
  1836. IMGkernelGlobal::WriteTextLog(_T("相片宽为0,存在未知错误"));
  1837. return FALSE;
  1838. }
  1839. // 旋转原图Image对象,使之正放;
  1840. INT nOrientation = GetOrientation(pImgCrop);
  1841. if ( nOrientation == 8 )
  1842. {
  1843. pImgCrop->RotateFlip(Rotate270FlipNone);
  1844. }
  1845. else if ( nOrientation == 6 )
  1846. {
  1847. pImgCrop->RotateFlip(Rotate90FlipNone);
  1848. }
  1849. // 计算出选片时缩略图与原图的缩放比例;
  1850. FLOAT fscal = 1.0;
  1851. fscal *= (float)pImgCrop->GetWidth() / (float)SrcImageWid;
  1852. // 缩略的裁剪位置*缩略比例=原片裁剪位置;
  1853. rcCrop.left *= fscal;
  1854. rcCrop.right *= fscal;
  1855. rcCrop.top *= fscal;
  1856. rcCrop.bottom *= fscal;
  1857. TString strSaveDirectory = lpSaveDirectory;
  1858. if (strSaveDirectory[strSaveDirectory.length() - 1] != _T('\\'))
  1859. strSaveDirectory.append(_T("\\"));
  1860. strSaveDirectory.append(_T("裁剪结果"));
  1861. strSaveDirectory.append(_T("\\"));
  1862. strSaveDirectory.append(strName);
  1863. strSaveDirectory.append(_T(":"));
  1864. strSaveDirectory.append(strCropScheme.GetString());
  1865. strSaveDirectory.append(_T(".jpg"));
  1866. Bitmap bp(rcCrop.Width(), rcCrop.Height());
  1867. Graphics *graphic = Graphics::FromImage(&bp);
  1868. graphic->Clear(Color(255, 255, 255, 255));
  1869. // 设置缩放或旋转图片时的算法(图片质量);
  1870. graphic->SetInterpolationMode(InterpolationModeHighQualityBicubic);
  1871. // 设置渲染图形对象的质量;
  1872. graphic->SetSmoothingMode(SmoothingModeHighQuality);//SmoothingModeHighSpeed
  1873. // 设置图形对象的像素偏移模式;
  1874. graphic->SetPixelOffsetMode(PixelOffsetModeHighQuality);
  1875. // 设置图形对象的合成模式;
  1876. graphic->SetCompositingMode(CompositingModeSourceOver);
  1877. // 设置图形对象的合成质量;
  1878. graphic->SetCompositingQuality(CompositingQualityHighQuality);
  1879. // 设置图形对象的文本渲染模式;
  1880. graphic->SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
  1881. graphic->DrawImage(pImgCrop, RectF(0, 0, rcCrop.Width(), rcCrop.Height()), rcCrop.left, rcCrop.top, rcCrop.Width(), rcCrop.Height(), UnitPixel);
  1882. if (pImgCrop)
  1883. delete pImgCrop;
  1884. if ( graphic)
  1885. delete graphic;
  1886. return SaveImg2newfile(&bp, strSaveDirectory, 100);
  1887. }
  1888. BOOL IMGCommon::CropImgToFile(IN CONST TString& strImgpath, IN TString& strCropFile, IN CRect& rcCrop)
  1889. {
  1890. if ( !PathFileExists(strImgpath.c_str()) )
  1891. {
  1892. return FALSE;
  1893. }
  1894. Image *pImgCrop = NULL;
  1895. if ( !LoadImgFromBuffer(&pImgCrop, strImgpath.c_str()) || pImgCrop == NULL )
  1896. {
  1897. IMGkernelGlobal::WriteTextLog(_T("加载相片失败"));
  1898. return FALSE;
  1899. }
  1900. if ( pImgCrop->GetWidth() == 0 )
  1901. {
  1902. IMGkernelGlobal::WriteTextLog(_T("相片宽为0,存在未知错误"));
  1903. return FALSE;
  1904. }
  1905. INT nOrientation = GetOrientation(pImgCrop);
  1906. if ( nOrientation == 8 )
  1907. {
  1908. pImgCrop->RotateFlip(Rotate270FlipNone);
  1909. }
  1910. else if ( nOrientation == 6 )
  1911. {
  1912. pImgCrop->RotateFlip(Rotate90FlipNone);
  1913. }
  1914. Bitmap bp(rcCrop.Width(), rcCrop.Height());
  1915. Graphics *graphic = Graphics::FromImage(&bp);
  1916. graphic->Clear(Color(255, 255, 255, 255));
  1917. // 设置缩放或旋转图片时的算法(图片质量);
  1918. graphic->SetInterpolationMode(InterpolationModeHighQualityBicubic);
  1919. // 设置渲染图形对象的质量;
  1920. graphic->SetSmoothingMode(SmoothingModeHighQuality);//SmoothingModeHighSpeed
  1921. // 设置图形对象的像素偏移模式;
  1922. graphic->SetPixelOffsetMode(PixelOffsetModeHighQuality);
  1923. // 设置图形对象的合成模式;
  1924. graphic->SetCompositingMode(CompositingModeSourceOver);
  1925. // 设置图形对象的合成质量;
  1926. graphic->SetCompositingQuality(CompositingQualityHighQuality);
  1927. // 设置图形对象的文本渲染模式;
  1928. graphic->SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
  1929. graphic->DrawImage(pImgCrop, RectF(0, 0, rcCrop.Width(), rcCrop.Height()), rcCrop.left, rcCrop.top, rcCrop.Width(), rcCrop.Height(), UnitPixel);
  1930. delete pImgCrop;
  1931. delete graphic;
  1932. return SaveImg2newfile(&bp, strCropFile, 100);
  1933. }
  1934. Image* IMGCommon::AppendImgWatermark(IN Image* pImg, IN Image* pWatemarkImg)
  1935. {
  1936. if ( pImg == NULL || pWatemarkImg == NULL )
  1937. return NULL;
  1938. // Status st = GenericError;
  1939. // 创建图像显示属性对象;
  1940. ImageAttributes ImgAttr;
  1941. // 创建新位图;
  1942. Bitmap *pBitmap = new Bitmap(pImg->GetWidth(), pImg->GetHeight(), PixelFormat32bppPARGB);
  1943. // 创建水印图显示位置;
  1944. RectF layWatemarkRect(10.0, 10.0, pWatemarkImg->GetWidth(), pWatemarkImg->GetHeight());
  1945. // 创建画布对象;
  1946. Graphics *grap = Graphics::FromImage(pBitmap);
  1947. // 绘制画布底色;
  1948. if ( Ok != grap->Clear(Color(255,255,255,255)) )
  1949. goto clear;
  1950. // 设置图片显示质量;
  1951. if ( Ok != grap->SetSmoothingMode(SmoothingModeAntiAlias) )
  1952. goto clear;
  1953. // 设置文本质量;
  1954. if ( Ok != grap->SetTextRenderingHint(TextRenderingHintAntiAlias))
  1955. goto clear;
  1956. // 在画布上画原始图片;
  1957. if ( Ok != grap->DrawImage(pImg, 0, 0, pImg->GetWidth(), pImg->GetHeight()) )
  1958. goto clear;
  1959. // 设置透明颜色为水印图片四角底色,水印图显示为圆角;
  1960. if ( Ok != ImgAttr.SetColorKey(0xFF00FF00, 0xFF00FF00, ColorAdjustTypeBitmap))
  1961. goto clear;
  1962. // 设置水印图片透明底为0.3;
  1963. if ( Ok != ImgAttr.SetColorMatrix(&_ClrMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap) )
  1964. goto clear;
  1965. // 在画布左上角画水印;
  1966. if ( Ok != grap->DrawImage(pWatemarkImg, layWatemarkRect, 0, 0, pWatemarkImg->GetWidth(), pWatemarkImg->GetHeight(), UnitPixel, &ImgAttr) )
  1967. goto clear;
  1968. if ( grap )
  1969. delete grap;
  1970. return pBitmap;
  1971. clear:
  1972. if ( grap )
  1973. delete grap;
  1974. if ( pBitmap )
  1975. delete pBitmap;
  1976. return NULL;
  1977. }
  1978. Image* IMGCommon::AppendImgWatermark(IN Image* pImg, IN LPCTSTR lpWatemarkImgpath)
  1979. {
  1980. if ( !PathFileExists(lpWatemarkImgpath) || pImg == NULL )
  1981. return FALSE;
  1982. #ifdef UNICODE
  1983. Image *pWatemarkImg = Image::FromFile(lpWatemarkImgpath);
  1984. #else
  1985. BSTR str = _bstr_t(lpWatemarkImgpath);
  1986. Image* pWatemarkImg = Image::FromFile(str);
  1987. SysFreeString(str);
  1988. #endif
  1989. if ( pImg == NULL )
  1990. return NULL;
  1991. //Status st = GenericError;
  1992. // 创建图像显示属性对象;
  1993. ImageAttributes ImgAttr;
  1994. // 创建新位图;
  1995. Bitmap *pBitmap = new Bitmap(pImg->GetWidth(), pImg->GetHeight(), PixelFormat32bppPARGB);
  1996. // 创建水印图显示位置;
  1997. RectF layWatemarkRect(10.0, 10.0, pWatemarkImg->GetWidth(), pWatemarkImg->GetHeight());
  1998. // 创建画布对象;
  1999. Graphics *grap = Graphics::FromImage(pBitmap);
  2000. // 绘制画布底色;
  2001. if ( Ok != grap->Clear(Color(255,255,255,255)) )
  2002. goto clear;
  2003. // 设置图片显示质量;
  2004. if ( Ok != grap->SetSmoothingMode(SmoothingModeAntiAlias) )
  2005. goto clear;
  2006. // 设置文本质量;
  2007. if ( Ok != grap->SetTextRenderingHint(TextRenderingHintAntiAlias))
  2008. goto clear;
  2009. // 在画布上画原始图片;
  2010. if ( Ok != grap->DrawImage(pImg, 0, 0, pImg->GetWidth(), pImg->GetHeight()) )
  2011. goto clear;
  2012. // 设置透明颜色为水印图片四角底色,水印图显示为圆角;
  2013. if ( Ok != ImgAttr.SetColorKey(0xFF00FF00, 0xFF00FF00, ColorAdjustTypeBitmap))
  2014. goto clear;
  2015. // 设置水印图片透明底为0.3;
  2016. if ( Ok != ImgAttr.SetColorMatrix(&_ClrMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap) )
  2017. goto clear;
  2018. // 在画布左上角画水印;
  2019. if ( Ok != grap->DrawImage(pWatemarkImg, layWatemarkRect, 0, 0, pWatemarkImg->GetWidth(), pWatemarkImg->GetHeight(), UnitPixel, &ImgAttr) )
  2020. goto clear;
  2021. if ( grap )
  2022. delete grap;
  2023. return pBitmap;
  2024. clear:
  2025. if ( grap )
  2026. delete grap;
  2027. if ( pBitmap )
  2028. delete pBitmap;
  2029. if ( pWatemarkImg )
  2030. delete pWatemarkImg;
  2031. return NULL;
  2032. }
  2033. Image* IMGCommon::AppendImgWatermark(IN LPCTSTR lpImgpath, IN Image* pWatemarkImg)
  2034. {
  2035. if ( !PathFileExists(lpImgpath) || pWatemarkImg == NULL )
  2036. return FALSE;
  2037. #ifdef UNICODE
  2038. Image *pImg = Image::FromFile(lpImgpath);
  2039. #else
  2040. BSTR str = _bstr_t(lpImgpath);
  2041. Image* pImg = Image::FromFile(str);
  2042. SysFreeString(str);
  2043. #endif
  2044. if ( pImg == NULL )
  2045. return NULL;
  2046. //Status st = GenericError;
  2047. // 创建图像显示属性对象;
  2048. ImageAttributes ImgAttr;
  2049. // 创建新位图;
  2050. Bitmap *pBitmap = new Bitmap(pImg->GetWidth(), pImg->GetHeight(), PixelFormat32bppPARGB);
  2051. // 创建水印图显示位置;
  2052. RectF layWatemarkRect(10.0, 10.0, pWatemarkImg->GetWidth(), pWatemarkImg->GetHeight());
  2053. // 创建画布对象;
  2054. Graphics *grap = Graphics::FromImage(pBitmap);
  2055. // 绘制画布底色;
  2056. if ( Ok != grap->Clear(Color(255,255,255,255)) )
  2057. goto clear;
  2058. // 设置图片显示质量;
  2059. if ( Ok != grap->SetSmoothingMode(SmoothingModeAntiAlias) )
  2060. goto clear;
  2061. // 设置文本质量;
  2062. if ( Ok != grap->SetTextRenderingHint(TextRenderingHintAntiAlias))
  2063. goto clear;
  2064. // 在画布上画原始图片;
  2065. if ( Ok != grap->DrawImage(pImg, 0, 0, pImg->GetWidth(), pImg->GetHeight()) )
  2066. goto clear;
  2067. // 设置透明颜色为水印图片四角底色,水印图显示为圆角;
  2068. if ( Ok != ImgAttr.SetColorKey(0xFF00FF00, 0xFF00FF00, ColorAdjustTypeBitmap))
  2069. goto clear;
  2070. // 设置水印图片透明底为0.3;
  2071. if ( Ok != ImgAttr.SetColorMatrix(&_ClrMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap) )
  2072. goto clear;
  2073. // 在画布左上角画水印;
  2074. if ( Ok != grap->DrawImage(pWatemarkImg, layWatemarkRect, 0, 0, pWatemarkImg->GetWidth(), pWatemarkImg->GetHeight(), UnitPixel, &ImgAttr) )
  2075. goto clear;
  2076. if ( grap )
  2077. delete grap;
  2078. return pBitmap;
  2079. clear:
  2080. if ( grap )
  2081. delete grap;
  2082. if ( pBitmap )
  2083. delete pBitmap;
  2084. if ( pImg )
  2085. delete pImg;
  2086. return NULL;
  2087. }
  2088. Image* IMGCommon::AppendImgWatermark(IN LPCTSTR lpImgpath, IN LPCTSTR lpWatemarkImgpath)
  2089. {
  2090. if ( !PathFileExists(lpImgpath) || !PathFileExists(lpWatemarkImgpath) )
  2091. return FALSE;
  2092. #ifdef UNICODE
  2093. Image *pImg = Image::FromFile(lpImgpath);
  2094. Image *pWatemarkImg = Image::FromFile(lpWatemarkImgpath);
  2095. #else
  2096. BSTR str = _bstr_t(lpImgpath);
  2097. Image* pImg = Image::FromFile(str);
  2098. SysFreeString(str);
  2099. BSTR str2 = _bstr_t(lpWatemarkImgpath);
  2100. Image* pWatemarkImg = Image::FromFile(str2);
  2101. SysFreeString(str2);
  2102. #endif
  2103. if ( pImg == NULL || pWatemarkImg == NULL )
  2104. return NULL;
  2105. //Status st = GenericError;
  2106. // 创建图像显示属性对象;
  2107. ImageAttributes ImgAttr;
  2108. // 创建新位图;
  2109. Bitmap *pBitmap = new Bitmap(pImg->GetWidth(), pImg->GetHeight(), PixelFormat32bppPARGB);
  2110. // 创建水印图显示位置;
  2111. RectF layWatemarkRect(10.0, 10.0, pWatemarkImg->GetWidth(), pWatemarkImg->GetHeight());
  2112. // 创建画布对象;
  2113. Graphics *grap = Graphics::FromImage(pBitmap);
  2114. // 绘制画布底色;
  2115. if ( Ok != grap->Clear(Color(255,255,255,255)) )
  2116. goto clear;
  2117. // 设置图片显示质量;
  2118. if ( Ok != grap->SetSmoothingMode(SmoothingModeAntiAlias) )
  2119. goto clear;
  2120. // 设置文本质量;
  2121. if ( Ok != grap->SetTextRenderingHint(TextRenderingHintAntiAlias))
  2122. goto clear;
  2123. // 在画布上画原始图片;
  2124. if ( Ok != grap->DrawImage(pImg, 0, 0, pImg->GetWidth(), pImg->GetHeight()) )
  2125. goto clear;
  2126. // 设置透明颜色为水印图片四角底色,水印图显示为圆角;
  2127. if ( Ok != ImgAttr.SetColorKey(0xFF00FF00, 0xFF00FF00, ColorAdjustTypeBitmap))
  2128. goto clear;
  2129. // 设置水印图片透明底为0.3;
  2130. if ( Ok != ImgAttr.SetColorMatrix(&_ClrMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap) )
  2131. goto clear;
  2132. // 在画布左上角画水印;
  2133. if ( Ok != grap->DrawImage(pWatemarkImg, layWatemarkRect, 0, 0, pWatemarkImg->GetWidth(), pWatemarkImg->GetHeight(), UnitPixel, &ImgAttr) )
  2134. goto clear;
  2135. if ( grap )
  2136. delete grap;
  2137. return pBitmap;
  2138. clear:
  2139. if ( grap )
  2140. delete grap;
  2141. if ( pBitmap )
  2142. delete pBitmap;
  2143. if ( pImg )
  2144. delete pImg;
  2145. if ( pWatemarkImg )
  2146. delete pWatemarkImg;
  2147. return NULL;
  2148. }
  2149. BOOL IMGCommon::AppendImgWatermark(IN Image* pImg, IN Image* pWatemarkImg, IN LPCTSTR lpSaveImgpath)
  2150. {
  2151. Image* pSaveImg = AppendImgWatermark(pImg, pWatemarkImg);
  2152. if ( pSaveImg == NULL )
  2153. return FALSE;
  2154. // 创建新的目录;
  2155. CString strImgs = lpSaveImgpath;
  2156. INT nIndex = strImgs.ReverseFind(_T('\\'));
  2157. if ( nIndex != -1 )
  2158. {
  2159. strImgs = strImgs.Mid(0,nIndex+1);
  2160. if ( !PathFileExists(strImgs) )
  2161. {
  2162. INT nRet = SHCreateDirectoryEx(NULL, strImgs, NULL);
  2163. if ( ERROR_SUCCESS == nRet || ERROR_ALREADY_EXISTS == nRet )
  2164. {
  2165. if (SaveImg2newfile(pSaveImg, (CString)lpSaveImgpath, 100))
  2166. {
  2167. if ( pSaveImg )
  2168. delete pSaveImg;
  2169. pSaveImg = NULL;
  2170. return TRUE;
  2171. }
  2172. return FALSE;
  2173. }
  2174. }
  2175. }
  2176. return FALSE;
  2177. }
  2178. BOOL IMGCommon::AppendImgWatermark(IN LPCTSTR lpImgpath, IN LPCTSTR lpWatemarkImgpath, IN LPCTSTR lpSaveImgpath)
  2179. {
  2180. Image *pSaveImg = AppendImgWatermark(lpImgpath, lpWatemarkImgpath);
  2181. if ( pSaveImg == NULL)
  2182. return FALSE;
  2183. // 创建新的目录;
  2184. CString strImgs = lpSaveImgpath;
  2185. INT nIndex = strImgs.ReverseFind(_T('\\'));
  2186. if ( nIndex != -1 )
  2187. {
  2188. strImgs = strImgs.Mid(0,nIndex+1);
  2189. if ( !PathFileExists(strImgs) )
  2190. {
  2191. INT nRet = SHCreateDirectoryEx(NULL, strImgs, NULL);
  2192. if ( ERROR_SUCCESS == nRet || ERROR_ALREADY_EXISTS == nRet )
  2193. {
  2194. if (SaveImg2newfile(pSaveImg, (CString)lpSaveImgpath, 100))
  2195. {
  2196. if ( pSaveImg )
  2197. delete pSaveImg;
  2198. pSaveImg = NULL;
  2199. return TRUE;
  2200. }
  2201. return FALSE;
  2202. }
  2203. }
  2204. }
  2205. return FALSE;
  2206. }
  2207. Image* IMGCommon::AppendWordWatermark(IN Image* pImg, IN LPCTSTR lpWatemarkString)
  2208. {
  2209. if ( pImg == NULL || lpWatemarkString == NULL || lpWatemarkString[0] == _T('\0'))
  2210. return NULL;
  2211. #ifndef UNICODE
  2212. WCHAR* pText = StringProcess::ascii2unicode(lpWatemarkString);
  2213. #endif
  2214. // 创建新位图;
  2215. Bitmap *pBitmap = new Bitmap(pImg->GetWidth(), pImg->GetHeight(), PixelFormat32bppPARGB);
  2216. // 创建字体;
  2217. FontFamily ffly(L"宋体");
  2218. Gdiplus::Font ft(&ffly, 24, FontStyleRegular, UnitPixel);
  2219. // 创建画刷;
  2220. SolidBrush brush(0x99000000);
  2221. // 创建文本格式;
  2222. StringFormat sf;
  2223. sf.SetAlignment(StringAlignmentCenter); // 水平居中;
  2224. // 创建水印文本显示位置;
  2225. RectF layWatemarkRect(pImg->GetWidth(), pImg->GetHeight() - 25, 0.0, 0.0); // 文字阴影;
  2226. RectF layWatemarkRect2(pImg->GetWidth(), pImg->GetHeight() - 26, 0.0, 0.0); // 文字原体;
  2227. // 创建画布对象;
  2228. Graphics *grap = Graphics::FromImage(pBitmap);
  2229. // 绘制画布底色;
  2230. if ( Ok != grap->Clear(Color(255,255,255,255)) )
  2231. goto clear;
  2232. // 设置图片显示质量;
  2233. if ( Ok != grap->SetSmoothingMode(SmoothingModeAntiAlias) )
  2234. goto clear;
  2235. // 设置文本质量;
  2236. if ( Ok != grap->SetTextRenderingHint(TextRenderingHintAntiAlias))
  2237. goto clear;
  2238. // 在画布上画原始图片;
  2239. if ( Ok != grap->DrawImage(pImg, 0, 0, pImg->GetWidth(), pImg->GetHeight()) )
  2240. goto clear;
  2241. // 画水印阴影;
  2242. #ifdef UNICODE
  2243. if ( Ok != grap->DrawString(lpWatemarkString, wcslen(lpWatemarkString), &ft, layWatemarkRect, &sf, &brush) )
  2244. #else
  2245. if ( Ok != grap->DrawString(pText, wcslen(pText), &ft, layWatemarkRect, &sf, &brush) )
  2246. #endif
  2247. goto clear;
  2248. // 画水印文本;
  2249. brush.SetColor(0x99ffffff);
  2250. #ifdef UNICODE
  2251. if ( Ok != grap->DrawString(lpWatemarkString, wcslen(lpWatemarkString), &ft, layWatemarkRect2, &sf, &brush) )
  2252. #else
  2253. if ( Ok != grap->DrawString(pText, wcslen(pText), &ft, layWatemarkRect, &sf, &brush) )
  2254. #endif
  2255. goto clear;
  2256. if ( grap )
  2257. delete grap;
  2258. return pBitmap;
  2259. clear:
  2260. if ( grap )
  2261. delete grap;
  2262. if ( pBitmap )
  2263. delete pBitmap;
  2264. if ( pImg )
  2265. delete pImg;
  2266. #ifndef UNICODE
  2267. if (pText)
  2268. delete []pText;
  2269. #endif
  2270. return NULL;
  2271. }
  2272. Image* IMGCommon::AppendWordWatermark(IN LPCTSTR lpImgpath, IN LPCTSTR lpWatemarkString)
  2273. {
  2274. if ( !PathFileExists(lpImgpath) || lpWatemarkString == NULL || lpWatemarkString[0] == _T('\0'))
  2275. return NULL;
  2276. #ifdef UNICODE
  2277. Image *pImg = Image::FromFile(lpImgpath);
  2278. #else
  2279. BSTR str = _bstr_t(lpImgpath);
  2280. Image* pImg = Image::FromFile(str);
  2281. SysFreeString(str);
  2282. #endif
  2283. #ifndef UNICODE
  2284. WCHAR* pText = StringProcess::ascii2unicode(lpWatemarkString);
  2285. #endif
  2286. // 创建新位图;
  2287. Bitmap *pBitmap = new Bitmap(pImg->GetWidth(), pImg->GetHeight(), PixelFormat32bppPARGB);
  2288. // 创建字体;
  2289. FontFamily ffly(L"宋体");
  2290. Gdiplus::Font ft(&ffly, 24, FontStyleRegular, UnitPixel);
  2291. // 创建画刷;
  2292. SolidBrush brush(0x99000000);
  2293. // 创建文本格式;
  2294. StringFormat sf;
  2295. sf.SetAlignment(StringAlignmentCenter); // 水平居中;
  2296. // 创建水印文本显示位置;
  2297. RectF layWatemarkRect(pImg->GetWidth(), pImg->GetHeight() - 25, 0.0, 0.0); // 文字阴影;
  2298. RectF layWatemarkRect2(pImg->GetWidth(), pImg->GetHeight() - 26, 0.0, 0.0); // 文字原体;
  2299. // 创建画布对象;
  2300. Graphics *grap = Graphics::FromImage(pBitmap);
  2301. // 绘制画布底色;
  2302. if ( Ok != grap->Clear(Color(255,255,255,255)) )
  2303. goto clear;
  2304. // 设置图片显示质量;
  2305. if ( Ok != grap->SetSmoothingMode(SmoothingModeAntiAlias) )
  2306. goto clear;
  2307. // 设置文本质量;
  2308. if ( Ok != grap->SetTextRenderingHint(TextRenderingHintAntiAlias))
  2309. goto clear;
  2310. // 在画布上画原始图片;
  2311. if ( Ok != grap->DrawImage(pImg, 0, 0, pImg->GetWidth(), pImg->GetHeight()) )
  2312. goto clear;
  2313. // 画水印阴影;
  2314. #ifdef UNICODE
  2315. if ( Ok != grap->DrawString(lpWatemarkString, wcslen(lpWatemarkString), &ft, layWatemarkRect, &sf, &brush) )
  2316. #else
  2317. if ( Ok != grap->DrawString(pText, wcslen(pText), &ft, layWatemarkRect, &sf, &brush) )
  2318. #endif
  2319. goto clear;
  2320. // 画水印文本;
  2321. brush.SetColor(0x99ffffff);
  2322. #ifdef UNICODE
  2323. if ( Ok != grap->DrawString(lpWatemarkString, wcslen(lpWatemarkString), &ft, layWatemarkRect2, &sf, &brush) )
  2324. #else
  2325. if ( Ok != grap->DrawString(pText, wcslen(pText), &ft, layWatemarkRect, &sf, &brush) )
  2326. #endif
  2327. goto clear;
  2328. if ( grap )
  2329. delete grap;
  2330. return pBitmap;
  2331. clear:
  2332. if ( grap )
  2333. delete grap;
  2334. if ( pBitmap )
  2335. delete pBitmap;
  2336. if ( pImg )
  2337. delete pImg;
  2338. #ifndef UNICODE
  2339. if (pText)
  2340. delete []pText;
  2341. #endif
  2342. return NULL;
  2343. }
  2344. BOOL IMGCommon::SaveBitmap(IN CDC *pDC, IN CBitmap* pBitmap, IN CONST INT& nBitdepth, IN const INT& nWidth, IN const INT& nHeight, IN LPCTSTR lpSavepath)
  2345. {
  2346. // 计算出位图大小 = ((宽 * 位宽 + 31)/ 32)* 4 * 高;
  2347. DWORD dwBmpSize = ((nWidth*nBitdepth + 31) / 32) * 4 * nHeight;
  2348. HANDLE hFile = CreateFile(lpSavepath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  2349. if (hFile == INVALID_HANDLE_VALUE)
  2350. {
  2351. //WriteLog(_T("二维码位图创建失败"));
  2352. return FALSE;
  2353. }
  2354. HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE | SEC_COMMIT, 0,
  2355. sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 2 + dwBmpSize, NULL);
  2356. LPBYTE lpbyMapView = (LPBYTE)MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, 0);
  2357. ZeroMemory(lpbyMapView, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 2 + dwBmpSize);
  2358. //结构体地址割付;
  2359. LPBITMAPFILEHEADER pbfh = (LPBITMAPFILEHEADER)lpbyMapView;
  2360. LPBITMAPINFO pbmi = (LPBITMAPINFO)(lpbyMapView + sizeof(BITMAPFILEHEADER));
  2361. LPVOID pbdt = lpbyMapView + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 2;
  2362. // BITMAPFILEHEADER
  2363. // pbfh->bfType = (WORD) (('M' << 8) | 'B'); // "BM"
  2364. // BMP类型,与上面同值;
  2365. pbfh->bfType = 0x4D42;
  2366. pbfh->bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 2 + dwBmpSize; // 文件总长;
  2367. pbfh->bfReserved1 = 0;
  2368. pbfh->bfReserved2 = 0;
  2369. pbfh->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 2; // 位图数据相对于文件头的偏移量;
  2370. // LPBITMAPINFO->BITMAPINFOHEADER
  2371. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  2372. pbmi->bmiHeader.biWidth = nWidth;
  2373. pbmi->bmiHeader.biHeight = nHeight;
  2374. pbmi->bmiHeader.biPlanes = 1;
  2375. pbmi->bmiHeader.biBitCount = nBitdepth; // 位深度 1;
  2376. pbmi->bmiHeader.biCompression = BI_RGB;
  2377. pbmi->bmiHeader.biSizeImage = dwBmpSize;
  2378. pbmi->bmiHeader.biXPelsPerMeter = 3780;
  2379. pbmi->bmiHeader.biYPelsPerMeter = 3780;
  2380. pbmi->bmiHeader.biClrUsed = 0;
  2381. pbmi->bmiHeader.biClrImportant = 0;
  2382. // 放大到指定的像素宽高;
  2383. CDC* pWorkDC = new CDC;
  2384. pWorkDC->CreateCompatibleDC(NULL);
  2385. CBitmap* pWorkBitmap = new CBitmap;
  2386. pWorkBitmap->CreateBitmap(nWidth, nHeight, 1, 1, NULL);
  2387. CBitmap* pOldBitmap = pWorkDC->SelectObject(pWorkBitmap);
  2388. pWorkDC->StretchBlt(0, 0, nWidth, nHeight, pDC, 0, 0, nWidth, nHeight, SRCCOPY);
  2389. GetDIBits(pWorkDC->m_hDC, (HBITMAP)*pWorkBitmap, 0, nHeight, pbdt, pbmi, DIB_RGB_COLORS);
  2390. pWorkDC->SelectObject(pOldBitmap);
  2391. delete pWorkBitmap;
  2392. delete pWorkDC;
  2393. UnmapViewOfFile(lpbyMapView);
  2394. CloseHandle(hFileMapping);
  2395. CloseHandle(hFile);
  2396. return TRUE;
  2397. }
  2398. /************************************************************************/
  2399. /* 函数:SaveBitmapEx[10/17/2016 IT];
  2400. /* 描述:将CDC上的位图保存成文件;
  2401. /* 参数:;
  2402. /* [IN] :;
  2403. /* [OUT] :;
  2404. /* [IN/OUT] :;
  2405. /* 返回:void;
  2406. /* 注意:位图大小 = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 调色板大小(16、24、32位深的调色板大小为0) + 位图数据大小;
  2407. /* 示例:;
  2408. /*
  2409. /* 修改:;
  2410. /* 日期:;
  2411. /* 内容:;
  2412. /************************************************************************/
  2413. BOOL IMGCommon::SaveBitmapEx(IN CDC *pDC, IN CBitmap* pBitmap, IN CONST INT& nBitdepth, IN const INT& nWidth, IN const INT& nHeight, IN LPCTSTR lpSavepath)
  2414. {
  2415. DWORD dwPaletteSize = 0; // 调色板大小;
  2416. DWORD dwBmBitsSize = 0; // 位图中像素字节大小;
  2417. DWORD dwDIBSize = 0; // 位图文件大小;
  2418. WORD wBitsCount = 0; // 当前显示分辨率下每个像素所占字节数;
  2419. if( nBitdepth <= 1 )
  2420. wBitsCount = 1;
  2421. else if( nBitdepth <= 4 )
  2422. wBitsCount = 4;
  2423. else if( nBitdepth <= 8 )
  2424. wBitsCount = 8;
  2425. else if( nBitdepth <= 16 )
  2426. wBitsCount = 16;
  2427. else if( nBitdepth <= 24 )
  2428. wBitsCount = 24;
  2429. else
  2430. wBitsCount = 32;
  2431. // 计算出调色板大小;
  2432. if( wBitsCount <= 8 )
  2433. dwPaletteSize = (1 << wBitsCount) * sizeof(RGBQUAD);
  2434. // 计算出位图数据大小 = ((宽 * 位宽 + 31)/ 32)* 4 * 高;
  2435. dwBmBitsSize = ((nWidth*wBitsCount + 31) / 8) * nHeight;
  2436. // 计算出位图文件大小;
  2437. dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
  2438. //////////////////////////////////////////////////////////////////////////
  2439. // 根据新位图来创建位图文件;
  2440. HANDLE hFile = CreateFile(lpSavepath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  2441. if (hFile == INVALID_HANDLE_VALUE)
  2442. {
  2443. return FALSE;
  2444. }
  2445. HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE | SEC_COMMIT, 0, dwDIBSize, NULL);
  2446. LPBYTE lpbyMapView = (LPBYTE)MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, 0);
  2447. ZeroMemory(lpbyMapView, dwDIBSize);
  2448. //结构体地址割付;
  2449. LPBITMAPFILEHEADER pbfh = (LPBITMAPFILEHEADER)lpbyMapView;
  2450. LPBITMAPINFO pbmi = (LPBITMAPINFO)(lpbyMapView + sizeof(BITMAPFILEHEADER));
  2451. LPVOID pbdt = lpbyMapView + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize;
  2452. // BITMAPFILEHEADER
  2453. // pbfh->bfType = (WORD) (('M' << 8) | 'B'); // "BM"
  2454. // BMP类型,与上面同值;
  2455. pbfh->bfType = 0x4D42;
  2456. pbfh->bfSize = dwDIBSize; // 文件总长;
  2457. pbfh->bfReserved1 = 0;
  2458. pbfh->bfReserved2 = 0;
  2459. pbfh->bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; // 位图数据相对于文件头的偏移量;
  2460. // LPBITMAPINFO->BITMAPINFOHEADER
  2461. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  2462. pbmi->bmiHeader.biWidth = nWidth;
  2463. pbmi->bmiHeader.biHeight = nHeight;
  2464. pbmi->bmiHeader.biPlanes = 1;
  2465. pbmi->bmiHeader.biBitCount = wBitsCount; // 位深度;
  2466. pbmi->bmiHeader.biCompression = BI_RGB;
  2467. pbmi->bmiHeader.biSizeImage = dwBmBitsSize; // 位图数据大小;
  2468. pbmi->bmiHeader.biXPelsPerMeter = 3780;
  2469. pbmi->bmiHeader.biYPelsPerMeter = 3780;
  2470. pbmi->bmiHeader.biClrUsed = 0;
  2471. pbmi->bmiHeader.biClrImportant = 0;
  2472. //////////////////////////////////////////////////////////////////////////
  2473. // 拉伸到指定的像素宽高;
  2474. CDC* pWorkDC = new CDC;
  2475. pWorkDC->CreateCompatibleDC(NULL);
  2476. CBitmap* pWorkBitmap = new CBitmap;
  2477. pWorkBitmap->CreateBitmap(nWidth, nHeight, 1, 1, NULL);
  2478. CBitmap* pOldBitmap = pWorkDC->SelectObject(pWorkBitmap);
  2479. pWorkDC->StretchBlt(0, 0, nWidth, nHeight, pDC, 0, 0, nWidth, nHeight, SRCCOPY);
  2480. GetDIBits(pWorkDC->GetSafeHdc(), (HBITMAP)*pWorkBitmap, 0, nHeight, pbdt, pbmi, DIB_RGB_COLORS);
  2481. pWorkDC->SelectObject(pOldBitmap);
  2482. delete pWorkBitmap;
  2483. delete pWorkDC;
  2484. UnmapViewOfFile(lpbyMapView);
  2485. CloseHandle(hFileMapping);
  2486. CloseHandle(hFile);
  2487. return TRUE;
  2488. }
  2489. void IMGCommon::DrawString(IN CDC* pdc, IN CONST INT& nFontSize, IN LPCTSTR lpFontName, IN LPCTSTR lpString, IN OUT CRect &rcString)
  2490. {
  2491. if ( !pdc || !lpString )
  2492. return;
  2493. LOGFONT log;
  2494. // 设置字体字号;
  2495. log.lfHeight = -MulDiv(nFontSize ? nFontSize : 9, GetDeviceCaps(pdc->GetSafeHdc(), LOGPIXELSY), 72);
  2496. log.lfWidth = 0;
  2497. log.lfEscapement = 0;
  2498. log.lfOrientation = 0;
  2499. log.lfWeight = FW_REGULAR;
  2500. log.lfItalic = false;
  2501. log.lfUnderline = false;
  2502. log.lfStrikeOut = 0;
  2503. log.lfCharSet = ANSI_CHARSET;
  2504. log.lfOutPrecision = OUT_DEFAULT_PRECIS;
  2505. log.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  2506. log.lfQuality = DEFAULT_QUALITY;
  2507. log.lfPitchAndFamily = DEFAULT_PITCH || FF_ROMAN;
  2508. // 设置字体名称;
  2509. _tcscpy_s(log.lfFaceName, (lpFontName && (lpFontName[0] != _T('\0'))) ? lpFontName : _T("Arial"));
  2510. CFont cf;
  2511. cf.CreateFontIndirect(&log);
  2512. CFont *oldf = pdc->SelectObject(&cf);
  2513. SIZE Size;
  2514. GetTextExtentPoint32(pdc->GetSafeHdc(), lpString, _tcslen(lpString), &Size);
  2515. rcString.SetRect(rcString.left, rcString.top, Size.cx + rcString.left, Size.cy + rcString.top);
  2516. pdc->TextOut(rcString.left, rcString.top, lpString);
  2517. }
  2518. HICON IMGCommon::GetFileIcon(IN const CString& strFilePath, IN BOOL bLarge)
  2519. {
  2520. SHFILEINFO SHFI;
  2521. ZeroMemory(&SHFI, sizeof(SHFI));
  2522. DWORD_PTR ret = ::SHGetFileInfo(strFilePath, 0, &SHFI, sizeof(SHFI),
  2523. SHGFI_ICON | (bLarge ? SHGFI_LARGEICON : SHGFI_SMALLICON));
  2524. if (ret != 0)
  2525. {
  2526. return SHFI.hIcon;
  2527. }
  2528. return NULL;
  2529. }