ImageHelper.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4. using System.IO;
  5. using System.Net;
  6. namespace FastReport.Utils
  7. {
  8. internal static class ImageHelper
  9. {
  10. public static Bitmap CloneBitmap(Image source)
  11. {
  12. if (source == null)
  13. return null;
  14. Bitmap image = new Bitmap(source.Width, source.Height);
  15. image.SetResolution(source.HorizontalResolution, source.VerticalResolution);
  16. using (Graphics g = Graphics.FromImage(image))
  17. {
  18. g.DrawImageUnscaled(source, 0, 0);
  19. }
  20. return image;
  21. // this can throw OutOfMemory when creating a grayscale image from a cloned bitmap
  22. // return source.Clone() as Bitmap;
  23. }
  24. public static void Save(Image image, Stream stream)
  25. {
  26. Save(image, stream, image.GetImageFormat());
  27. }
  28. public static void Save(Image image, string fileName, ImageFormat format)
  29. {
  30. using (FileStream stream = new FileStream(fileName, FileMode.Create))
  31. {
  32. Save(image, stream, format);
  33. }
  34. }
  35. public static void Save(Image image, Stream stream, ImageFormat format)
  36. {
  37. if (image == null)
  38. return;
  39. if (image is Bitmap)
  40. {
  41. if (format == ImageFormat.Icon)
  42. SaveAsIcon(image, stream, true);
  43. else
  44. image.Save(stream, format);
  45. }
  46. else if (image is Metafile)
  47. {
  48. Metafile emf = null;
  49. using (Bitmap bmp = new Bitmap(1, 1))
  50. using (Graphics g = Graphics.FromImage(bmp))
  51. {
  52. IntPtr hdc = g.GetHdc();
  53. emf = new Metafile(stream, hdc);
  54. g.ReleaseHdc(hdc);
  55. }
  56. using (Graphics g = Graphics.FromImage(emf))
  57. {
  58. g.DrawImage(image, 0, 0);
  59. }
  60. }
  61. }
  62. public static bool SaveAndConvert(Image image, Stream stream, ImageFormat format)
  63. {
  64. if (image == null)
  65. return false;
  66. if (format == ImageFormat.Jpeg || format == ImageFormat.Gif
  67. || format == ImageFormat.Tiff || format == ImageFormat.Bmp
  68. || format == ImageFormat.Png
  69. || format == ImageFormat.MemoryBmp)
  70. {
  71. if (image is Bitmap)
  72. {
  73. if (format == ImageFormat.MemoryBmp)
  74. throw new Exception(Res.Get("Export,Image,ImageParceFormatException"));
  75. image.Save(stream, format);
  76. return true;
  77. }
  78. //from mf to bitmap
  79. using (Metafile metafile = image as Metafile)
  80. using (Bitmap bitmap = new Bitmap(image.Width, image.Height))
  81. {
  82. bitmap.SetResolution(96F, 96F);
  83. using (Graphics g = Graphics.FromImage(bitmap))
  84. {
  85. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
  86. g.DrawImage(metafile, 0, 0, (float)image.Width, (float)image.Height);
  87. g.Dispose();
  88. }
  89. bitmap.Save(stream, format);
  90. }
  91. return true;
  92. }
  93. else if (format == ImageFormat.Icon)
  94. {
  95. return SaveAsIcon(image, stream, true);
  96. }
  97. else if (format == ImageFormat.Wmf || format == ImageFormat.Emf)
  98. {
  99. if (image is Metafile)
  100. {
  101. Metafile emf = null;
  102. using (Bitmap bmp = new Bitmap(1, 1))
  103. using (Graphics g = Graphics.FromImage(bmp))
  104. {
  105. IntPtr hdc = g.GetHdc();
  106. emf = new Metafile(stream, hdc);
  107. g.ReleaseHdc(hdc);
  108. }
  109. using (Graphics g = Graphics.FromImage(emf))
  110. {
  111. g.DrawImage(image, 0, 0);
  112. }
  113. return true;
  114. }
  115. }
  116. //throw new Exception(Res.Get("Export,Image,ImageParceFormatException")); // we cant convert image to exif or from bitmap to mf
  117. return false;
  118. }
  119. public static byte[] Load(string fileName)
  120. {
  121. if (!String.IsNullOrEmpty(fileName))
  122. return File.ReadAllBytes(fileName);
  123. return null;
  124. }
  125. public static Image Load(byte[] bytes)
  126. {
  127. if (bytes != null && bytes.Length > 0)
  128. {
  129. try
  130. {
  131. #if CROSSPLATFORM
  132. // TODO memory leaks image converter
  133. return Image.FromStream(new MemoryStream(bytes));
  134. #else
  135. return new ImageConverter().ConvertFrom(bytes) as Image;
  136. #endif
  137. }
  138. catch
  139. {
  140. Bitmap errorBmp = new Bitmap(10, 10);
  141. using (Graphics g = Graphics.FromImage(errorBmp))
  142. {
  143. g.DrawLine(Pens.Red, 0, 0, 10, 10);
  144. g.DrawLine(Pens.Red, 0, 10, 10, 0);
  145. }
  146. return errorBmp;
  147. }
  148. }
  149. return null;
  150. }
  151. public static byte[] LoadURL(string url)
  152. {
  153. if (!String.IsNullOrEmpty(url))
  154. {
  155. System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc0 | 0x300 | 0xc00);
  156. using (WebClient web = new WebClient())
  157. {
  158. return web.DownloadData(url);
  159. }
  160. }
  161. return null;
  162. }
  163. public static Bitmap GetTransparentBitmap(Image source, float transparency)
  164. {
  165. if (source == null)
  166. return null;
  167. ColorMatrix colorMatrix = new ColorMatrix();
  168. colorMatrix.Matrix33 = 1 - transparency;
  169. ImageAttributes imageAttributes = new ImageAttributes();
  170. imageAttributes.SetColorMatrix(
  171. colorMatrix,
  172. ColorMatrixFlag.Default,
  173. ColorAdjustType.Bitmap);
  174. int width = source.Width;
  175. int height = source.Height;
  176. Bitmap image = new Bitmap(width, height);
  177. image.SetResolution(source.HorizontalResolution, source.VerticalResolution);
  178. using (Graphics g = Graphics.FromImage(image))
  179. {
  180. g.Clear(Color.Transparent);
  181. g.DrawImage(
  182. source,
  183. new Rectangle(0, 0, width, height),
  184. 0, 0, width, height,
  185. GraphicsUnit.Pixel,
  186. imageAttributes);
  187. }
  188. return image;
  189. }
  190. public static Bitmap GetGrayscaleBitmap(Image source)
  191. {
  192. Bitmap grayscaleBitmap = new Bitmap(source.Width, source.Height, source.PixelFormat);
  193. // Red should be converted to (R*.299)+(G*.587)+(B*.114)
  194. // Green should be converted to (R*.299)+(G*.587)+(B*.114)
  195. // Blue should be converted to (R*.299)+(G*.587)+(B*.114)
  196. // Alpha should stay the same.
  197. ColorMatrix grayscaleMatrix = new ColorMatrix(new float[][]{
  198. new float[] {0.299f, 0.299f, 0.299f, 0, 0},
  199. new float[] {0.587f, 0.587f, 0.587f, 0, 0},
  200. new float[] {0.114f, 0.114f, 0.114f, 0, 0},
  201. new float[] { 0, 0, 0, 1, 0},
  202. new float[] { 0, 0, 0, 0, 1}});
  203. ImageAttributes attributes = new ImageAttributes();
  204. attributes.SetColorMatrix(grayscaleMatrix);
  205. // Use a Graphics object from the new image
  206. using (Graphics graphics = Graphics.FromImage(grayscaleBitmap))
  207. {
  208. // Draw the original image using the ImageAttributes we created
  209. graphics.DrawImage(source,
  210. new Rectangle(0, 0, grayscaleBitmap.Width, grayscaleBitmap.Height),
  211. 0, 0, grayscaleBitmap.Width, grayscaleBitmap.Height,
  212. GraphicsUnit.Pixel, attributes);
  213. }
  214. return grayscaleBitmap;
  215. }
  216. /// <summary>
  217. /// Converts a PNG image to a icon (ico)
  218. /// </summary>
  219. /// <param name="image">The input image</param>
  220. /// <param name="output">The output stream</param>
  221. /// <param name="preserveAspectRatio">Preserve the aspect ratio</param>
  222. /// <returns>Wether or not the icon was succesfully generated</returns>
  223. public static bool SaveAsIcon(Image image, Stream output, bool preserveAspectRatio = false)
  224. {
  225. int size = 256;
  226. float width = size, height = size;
  227. if (preserveAspectRatio)
  228. {
  229. if (image.Width > image.Height)
  230. height = ((float)image.Height / image.Width) * size;
  231. else
  232. width = ((float)image.Width / image.Height) * size;
  233. }
  234. var newBitmap = new Bitmap(image, new Size((int)width, (int)height));
  235. if (newBitmap == null)
  236. return false;
  237. // save the resized png into a memory stream for future use
  238. using (MemoryStream memoryStream = new MemoryStream())
  239. {
  240. newBitmap.Save(memoryStream, ImageFormat.Png);
  241. var iconWriter = new BinaryWriter(output);
  242. if (output == null || iconWriter == null)
  243. return false;
  244. // 0-1 reserved, 0
  245. iconWriter.Write((byte)0);
  246. iconWriter.Write((byte)0);
  247. // 2-3 image type, 1 = icon, 2 = cursor
  248. iconWriter.Write((short)1);
  249. // 4-5 number of images
  250. iconWriter.Write((short)1);
  251. // image entry 1
  252. // 0 image width
  253. iconWriter.Write((byte)width);
  254. // 1 image height
  255. iconWriter.Write((byte)height);
  256. // 2 number of colors
  257. iconWriter.Write((byte)0);
  258. // 3 reserved
  259. iconWriter.Write((byte)0);
  260. // 4-5 color planes
  261. iconWriter.Write((short)0);
  262. // 6-7 bits per pixel
  263. iconWriter.Write((short)32);
  264. // 8-11 size of image data
  265. iconWriter.Write((int)memoryStream.Length);
  266. // 12-15 offset of image data
  267. iconWriter.Write((int)(6 + 16));
  268. // write image data
  269. // png data must contain the whole png data file
  270. iconWriter.Write(memoryStream.ToArray());
  271. iconWriter.Flush();
  272. }
  273. return true;
  274. }
  275. }
  276. public static class ImageExtension
  277. {
  278. /// <summary>
  279. /// Returns an Image format.
  280. /// </summary>
  281. public static ImageFormat GetImageFormat(this Image bitmap)
  282. {
  283. if (bitmap == null || bitmap.RawFormat == null)
  284. return null;
  285. ImageFormat format = null;
  286. if (ImageFormat.Jpeg.Equals(bitmap.RawFormat))
  287. {
  288. format = ImageFormat.Jpeg;
  289. }
  290. else if (ImageFormat.Gif.Equals(bitmap.RawFormat))
  291. {
  292. format = ImageFormat.Gif;
  293. }
  294. else if (ImageFormat.Png.Equals(bitmap.RawFormat))
  295. {
  296. format = ImageFormat.Png;
  297. }
  298. else if (ImageFormat.Emf.Equals(bitmap.RawFormat))
  299. {
  300. format = ImageFormat.Emf;
  301. }
  302. else if (ImageFormat.Icon.Equals(bitmap.RawFormat))
  303. {
  304. format = ImageFormat.Icon;
  305. }
  306. else if (ImageFormat.Tiff.Equals(bitmap.RawFormat))
  307. {
  308. format = ImageFormat.Tiff;
  309. }
  310. else if (ImageFormat.Bmp.Equals(bitmap.RawFormat) || ImageFormat.MemoryBmp.Equals(bitmap.RawFormat)) // MemoryBmp format raises a GDI exception
  311. {
  312. format = ImageFormat.Bmp;
  313. }
  314. else if (ImageFormat.Wmf.Equals(bitmap.RawFormat))
  315. {
  316. format = ImageFormat.Wmf;
  317. }
  318. if (format != null)
  319. return format;
  320. return ImageFormat.Bmp;
  321. }
  322. }
  323. }