Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

449 lines
11 KiB

  1. /**************************************************************************
  2. *
  3. * Copyright (c) 2000 Microsoft Corporation
  4. *
  5. * Program Name:
  6. *
  7. * Crop
  8. *
  9. * This is a sample application that loads an image and shrinks it down
  10. * to 128x96 using the HighQualityBicubic resampling filter. It crops the
  11. * image to preserve the aspect ratio.
  12. *
  13. * This app is particularly useful for creating a set of thumbnail images
  14. * from a directory of pictures for use in a web page index.
  15. *
  16. * This example will produce a directory (idx) containing 128x96 jpeg
  17. * thumbnails for all the jpeg files in the pictures directory:
  18. * cd pictures
  19. * md idx
  20. * for %i in (*.jpg) do crop %~nxi idx\%~nxi
  21. *
  22. * Usage (command line):
  23. *
  24. * Crop input_filename output_filename
  25. *
  26. * Created:
  27. *
  28. * 06/25/2000 asecchia
  29. * Created it.
  30. * 03/16/2001 minliu
  31. * add -w, -h, -? -s, -q switches support. New ValidateArguments() and
  32. * USAGE() function
  33. * 05/10/2001 gillesk
  34. * added -a to crop the excess of the file and keep the w and h
  35. *
  36. **************************************************************************/
  37. #include <stdio.h>
  38. #include <windows.h>
  39. #include <objbase.h>
  40. #include <gdiplus.h>
  41. #include "../gpinit.inc"
  42. INT AsciiToUnicodeStr(
  43. const CHAR* ansiStr,
  44. WCHAR* unicodeStr,
  45. INT unicodeSize
  46. )
  47. {
  48. return( MultiByteToWideChar(
  49. CP_ACP,
  50. 0,
  51. ansiStr,
  52. -1,
  53. unicodeStr,
  54. unicodeSize
  55. ) > 0 );
  56. }
  57. int round(float f) { return (int) (f+0.5); }
  58. const int k_xsize = 128; // default thumbnail size
  59. const int k_ysize = 96;
  60. int g_xsize = k_xsize;
  61. int g_ysize = k_ysize;
  62. float g_scale = 1;
  63. int g_quality = 5;
  64. int g_compression = 70;
  65. BOOL g_HasSetScaleFactor = FALSE;
  66. BOOL g_KeepAspectRation = FALSE;
  67. BOOL g_GotFileNames = FALSE;
  68. WCHAR filename[1024];
  69. WCHAR outfilename[1024];
  70. #define Fail() goto cleanup
  71. void
  72. USAGE()
  73. {
  74. printf("******************************************************\n");
  75. printf("Usage: crop [-?] [-w width] [-h height] [-s factor] srcImg dstImg\n");
  76. printf("-w----Specify the thumbnail image width. Default is 128\n");
  77. printf("-h----Specify the thumbnail image height. Default is 96\n");
  78. printf("-s----Specify the scale factor\n");
  79. printf("-q----Specify the render quality [1-5] where 5(default) is the best\n");
  80. printf("-a----Keep the apsect ratio and crop the excess of the image\n");
  81. printf("-c----Set the compression factor [0-100] where 100 is least compressed\n");
  82. printf("-?----Print this usage message\n");
  83. printf("Note: If scale factor is specified, then width and height you specified are ignored\n\n\n");
  84. printf("Sample usage:\n");
  85. printf(" crop -w 200 -h 300 foo.jpg thumb.jpg\n");
  86. printf(" crop -s 0.5 foo.jpg thumb.jpg\n");
  87. printf(" crop foo.jpg thumb.jpg\n");
  88. }// USAGE()
  89. void
  90. ValidateArguments(int argc,
  91. char* argv[])
  92. {
  93. argc--;
  94. argv++; // Filter out program name
  95. while ( argc > 0 )
  96. {
  97. if ( strcmp(*argv, "-w") == 0 )
  98. {
  99. argc--;
  100. argv++;
  101. if ( argc == 0 )
  102. {
  103. // Not enough parameters
  104. USAGE();
  105. exit(1);
  106. }
  107. g_xsize = atoi(*argv++);
  108. argc--;
  109. }
  110. else if ( strcmp(*argv, "-h") == 0 )
  111. {
  112. argc--;
  113. argv++;
  114. if ( argc == 0 )
  115. {
  116. // Not enough parameters
  117. USAGE();
  118. exit(1);
  119. }
  120. g_ysize = atoi(*argv++);
  121. argc--;
  122. }
  123. else if ( strcmp(*argv, "-s") == 0 )
  124. {
  125. argc--;
  126. argv++;
  127. if ( argc == 0 )
  128. {
  129. // Not enough parameters
  130. USAGE();
  131. exit(1);
  132. }
  133. g_scale = (float)atof(*argv++);
  134. g_HasSetScaleFactor = TRUE;
  135. argc--;
  136. }
  137. else if ( strcmp(*argv, "-q") == 0 )
  138. {
  139. argc--;
  140. argv++;
  141. if ( argc == 0 )
  142. {
  143. // Not enough parameters
  144. USAGE();
  145. exit(1);
  146. }
  147. g_quality = atoi(*argv++);
  148. argc--;
  149. }
  150. else if ( strcmp(*argv, "-a") == 0 )
  151. {
  152. g_KeepAspectRation = TRUE;
  153. argc--;
  154. argv++;
  155. }
  156. else if ( strcmp(*argv, "-c") == 0 )
  157. {
  158. argc--;
  159. argv++;
  160. if ( argc == 0 )
  161. {
  162. // Not enough parameters
  163. USAGE();
  164. exit(1);
  165. }
  166. g_compression = atoi(*argv++);
  167. argc--;
  168. }
  169. else if ( strcmp(*argv, "-?") == 0 )
  170. {
  171. USAGE();
  172. exit(1);
  173. }
  174. else
  175. {
  176. // source and dest image name
  177. if ( argc < 2 )
  178. {
  179. // Not enough parameters
  180. USAGE();
  181. exit(1);
  182. }
  183. AsciiToUnicodeStr(*argv++, filename, 1024);
  184. argc--;
  185. AsciiToUnicodeStr(*argv++, outfilename, 1024);
  186. argc--;
  187. g_GotFileNames = TRUE;
  188. }
  189. }// while ( argc > 0 )
  190. if ( g_GotFileNames == FALSE )
  191. {
  192. // No input file name yet, bail out
  193. USAGE();
  194. exit(1);
  195. }
  196. }// ValidateArguments()
  197. void _cdecl
  198. main(int argc,
  199. char **argv
  200. )
  201. {
  202. if (!gGdiplusInitHelper.IsValid())
  203. {
  204. printf("error - GDI+ initialization failed\n");
  205. return;
  206. }
  207. // Parse input parameters
  208. ValidateArguments(argc, argv);
  209. using namespace Gdiplus;
  210. Status status = Ok;
  211. ImageCodecInfo* codecs = NULL;
  212. UINT count;
  213. UINT cbCodecs;
  214. // Open the source image
  215. Bitmap* dstBmp = NULL;
  216. Graphics *gdst = NULL;
  217. RectF srcRect;
  218. Bitmap *srcBmp = new Bitmap(filename, TRUE);
  219. if ( (srcBmp == NULL) || (srcBmp->GetLastStatus() != Ok) )
  220. {
  221. printf("Error opening image %s\n", filename);
  222. Fail();
  223. }
  224. // Ask the source image for it's size.
  225. int width = srcBmp->GetWidth();
  226. int height = srcBmp->GetHeight();
  227. srcRect = RectF(0.0f, 0.0f, (REAL)width, (REAL)height);
  228. printf("Input image is %d x %d\n", width, height);
  229. // Compute the optimal scale factor without changing the aspect ratio
  230. if ( g_HasSetScaleFactor == FALSE )
  231. {
  232. float scalex = (float)g_xsize / width;
  233. float scaley = (float)g_ysize / height;
  234. g_scale = min(scalex, scaley);
  235. }
  236. // If we want to keep the aspect ratio, then we need to crop the srcBmp
  237. UINT dstWidth = (UINT)(width * g_scale + 0.5);
  238. UINT dstHeight = (UINT)(height * g_scale + 0.5);
  239. if ( g_KeepAspectRation == TRUE )
  240. {
  241. float scalex = (float)g_xsize / width;
  242. float scaley = (float)g_ysize / height;
  243. g_scale = max(scalex, scaley);
  244. srcRect = RectF((REAL)width/2.0f, (REAL)height/2.0f, 0.0f, 0.0f);
  245. srcRect.Inflate(g_xsize/g_scale/2.0f, g_ysize/g_scale/2.0f);
  246. dstWidth = g_xsize;
  247. dstHeight = g_ysize;
  248. }
  249. // Create a destination image to draw onto
  250. dstBmp = new Bitmap(dstWidth, dstHeight, PixelFormat32bppPARGB);
  251. if ( (dstBmp == NULL) || (dstBmp->GetLastStatus() != Ok) )
  252. {
  253. printf("Error create temp Bitmap with size %d x %x\n", dstWidth,
  254. dstHeight);
  255. Fail();
  256. }
  257. gdst = new Graphics(dstBmp);
  258. if ( (gdst == NULL) || (gdst->GetLastStatus() != Ok) )
  259. {
  260. printf("Error create graphics\n");
  261. Fail();
  262. }
  263. // Make up a dest rect that we need image to draw to
  264. {
  265. RectF dstRect(0.0f, 0.0f, (REAL)dstWidth, (REAL)dstHeight);
  266. // Set the resampling quality to the bicubic filter
  267. switch ( g_quality )
  268. {
  269. case 1:
  270. gdst->SetInterpolationMode(InterpolationModeBilinear);
  271. break;
  272. case 2:
  273. gdst->SetInterpolationMode(InterpolationModeNearestNeighbor);
  274. break;
  275. case 3:
  276. gdst->SetInterpolationMode(InterpolationModeBicubic);
  277. break;
  278. case 4:
  279. gdst->SetInterpolationMode(InterpolationModeHighQualityBilinear);
  280. break;
  281. case 5:
  282. default:
  283. gdst->SetInterpolationMode(InterpolationModeHighQualityBicubic);
  284. break;
  285. }
  286. // Set the compositing quality to copy source pixels rather than
  287. // alpha blending. This will preserve any alpha in the source image.
  288. gdst->SetCompositingMode(CompositingModeSourceCopy);
  289. // Draw the source image onto the destination with the correct scale
  290. // and quality settings.
  291. status = gdst->DrawImage(srcBmp,
  292. dstRect,
  293. srcRect.X,
  294. srcRect.Y,
  295. srcRect.Width,
  296. srcRect.Height,
  297. UnitPixel
  298. );
  299. if (status != Ok)
  300. {
  301. printf("Error drawing the image\n");
  302. Fail();
  303. }
  304. }
  305. // Now start finding a codec to output the image.
  306. cbCodecs = 0;
  307. GetImageEncodersSize(&count, &cbCodecs);
  308. // Allocate space for the codec list
  309. codecs = static_cast<ImageCodecInfo *>(malloc (cbCodecs));
  310. if (codecs == NULL)
  311. {
  312. printf("error: failed to allocate memory for codecs\n");
  313. Fail();
  314. }
  315. // Get the list of encoders
  316. status = GetImageEncoders(count, cbCodecs, codecs);
  317. if (status != Ok)
  318. {
  319. printf("Error: GetImageEncoders returned %d\n", status);
  320. Fail();
  321. }
  322. // Search the codec list for the JPEG codec.
  323. // Use the Mime Type field to specify the correct codec.
  324. for(UINT i=0; i<count; i++) {
  325. if(wcscmp(codecs[i].MimeType, L"image/jpeg")==0) {break;}
  326. }
  327. if(i>=count)
  328. {
  329. fprintf(stderr, "failed to find the codec\n");
  330. Fail();
  331. }
  332. // Output the image to disk.
  333. CLSID tempClsID;
  334. tempClsID = codecs[i].Clsid;
  335. EncoderParameters params;
  336. params.Count = 1;
  337. params.Parameter[0].Guid = EncoderCompression;
  338. params.Parameter[0].NumberOfValues = 1;
  339. params.Parameter[0].Type = EncoderParameterValueTypeLong;
  340. params.Parameter[0].Value = (void*) &g_compression;
  341. status = dstBmp->Save(
  342. outfilename,
  343. &tempClsID,
  344. &params
  345. );
  346. if (status != Ok)
  347. {
  348. fprintf(stderr, "SaveImage--Save() failed\n");
  349. Fail();
  350. }
  351. printf("Create new image at %d x %d\n", dstWidth, dstHeight);
  352. // We're golden - everything worked.
  353. printf("Done\n");
  354. // Clean up the objects we used.
  355. cleanup:
  356. free(codecs);
  357. delete gdst;
  358. delete dstBmp;
  359. delete srcBmp;
  360. }