using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Net; namespace FastReport.Utils { internal static class ImageHelper { public static Bitmap CloneBitmap(Image source) { if (source == null) return null; Bitmap image = new Bitmap(source.Width, source.Height); image.SetResolution(source.HorizontalResolution, source.VerticalResolution); using (Graphics g = Graphics.FromImage(image)) { g.DrawImageUnscaled(source, 0, 0); } return image; // this can throw OutOfMemory when creating a grayscale image from a cloned bitmap // return source.Clone() as Bitmap; } public static void Save(Image image, Stream stream) { Save(image, stream, image.GetImageFormat()); } public static void Save(Image image, string fileName, ImageFormat format) { using (FileStream stream = new FileStream(fileName, FileMode.Create)) { Save(image, stream, format); } } public static void Save(Image image, Stream stream, ImageFormat format) { if (image == null) return; if (image is Bitmap) { if (format == ImageFormat.Icon) SaveAsIcon(image, stream, true); else image.Save(stream, format); } else if (image is Metafile) { Metafile emf = null; using (Bitmap bmp = new Bitmap(1, 1)) using (Graphics g = Graphics.FromImage(bmp)) { IntPtr hdc = g.GetHdc(); emf = new Metafile(stream, hdc); g.ReleaseHdc(hdc); } using (Graphics g = Graphics.FromImage(emf)) { g.DrawImage(image, 0, 0); } } } public static bool SaveAndConvert(Image image, Stream stream, ImageFormat format) { if (image == null) return false; if (format == ImageFormat.Jpeg || format == ImageFormat.Gif || format == ImageFormat.Tiff || format == ImageFormat.Bmp || format == ImageFormat.Png || format == ImageFormat.MemoryBmp) { if (image is Bitmap) { if (format == ImageFormat.MemoryBmp) throw new Exception(Res.Get("Export,Image,ImageParceFormatException")); image.Save(stream, format); return true; } //from mf to bitmap using (Metafile metafile = image as Metafile) using (Bitmap bitmap = new Bitmap(image.Width, image.Height)) { bitmap.SetResolution(96F, 96F); using (Graphics g = Graphics.FromImage(bitmap)) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.DrawImage(metafile, 0, 0, (float)image.Width, (float)image.Height); g.Dispose(); } bitmap.Save(stream, format); } return true; } else if (format == ImageFormat.Icon) { return SaveAsIcon(image, stream, true); } else if (format == ImageFormat.Wmf || format == ImageFormat.Emf) { if (image is Metafile) { Metafile emf = null; using (Bitmap bmp = new Bitmap(1, 1)) using (Graphics g = Graphics.FromImage(bmp)) { IntPtr hdc = g.GetHdc(); emf = new Metafile(stream, hdc); g.ReleaseHdc(hdc); } using (Graphics g = Graphics.FromImage(emf)) { g.DrawImage(image, 0, 0); } return true; } } //throw new Exception(Res.Get("Export,Image,ImageParceFormatException")); // we cant convert image to exif or from bitmap to mf return false; } public static byte[] Load(string fileName) { if (!String.IsNullOrEmpty(fileName)) return File.ReadAllBytes(fileName); return null; } public static Image Load(byte[] bytes) { if (bytes != null && bytes.Length > 0) { try { #if CROSSPLATFORM // TODO memory leaks image converter return Image.FromStream(new MemoryStream(bytes)); #else return new ImageConverter().ConvertFrom(bytes) as Image; #endif } catch { Bitmap errorBmp = new Bitmap(10, 10); using (Graphics g = Graphics.FromImage(errorBmp)) { g.DrawLine(Pens.Red, 0, 0, 10, 10); g.DrawLine(Pens.Red, 0, 10, 10, 0); } return errorBmp; } } return null; } public static byte[] LoadURL(string url) { if (!String.IsNullOrEmpty(url)) { System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc0 | 0x300 | 0xc00); using (WebClient web = new WebClient()) { return web.DownloadData(url); } } return null; } public static Bitmap GetTransparentBitmap(Image source, float transparency) { if (source == null) return null; ColorMatrix colorMatrix = new ColorMatrix(); colorMatrix.Matrix33 = 1 - transparency; ImageAttributes imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix( colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); int width = source.Width; int height = source.Height; Bitmap image = new Bitmap(width, height); image.SetResolution(source.HorizontalResolution, source.VerticalResolution); using (Graphics g = Graphics.FromImage(image)) { g.Clear(Color.Transparent); g.DrawImage( source, new Rectangle(0, 0, width, height), 0, 0, width, height, GraphicsUnit.Pixel, imageAttributes); } return image; } public static Bitmap GetGrayscaleBitmap(Image source) { Bitmap grayscaleBitmap = new Bitmap(source.Width, source.Height, source.PixelFormat); // Red should be converted to (R*.299)+(G*.587)+(B*.114) // Green should be converted to (R*.299)+(G*.587)+(B*.114) // Blue should be converted to (R*.299)+(G*.587)+(B*.114) // Alpha should stay the same. ColorMatrix grayscaleMatrix = new ColorMatrix(new float[][]{ new float[] {0.299f, 0.299f, 0.299f, 0, 0}, new float[] {0.587f, 0.587f, 0.587f, 0, 0}, new float[] {0.114f, 0.114f, 0.114f, 0, 0}, new float[] { 0, 0, 0, 1, 0}, new float[] { 0, 0, 0, 0, 1}}); ImageAttributes attributes = new ImageAttributes(); attributes.SetColorMatrix(grayscaleMatrix); // Use a Graphics object from the new image using (Graphics graphics = Graphics.FromImage(grayscaleBitmap)) { // Draw the original image using the ImageAttributes we created graphics.DrawImage(source, new Rectangle(0, 0, grayscaleBitmap.Width, grayscaleBitmap.Height), 0, 0, grayscaleBitmap.Width, grayscaleBitmap.Height, GraphicsUnit.Pixel, attributes); } return grayscaleBitmap; } /// /// Converts a PNG image to a icon (ico) /// /// The input image /// The output stream /// Preserve the aspect ratio /// Wether or not the icon was succesfully generated public static bool SaveAsIcon(Image image, Stream output, bool preserveAspectRatio = false) { int size = 256; float width = size, height = size; if (preserveAspectRatio) { if (image.Width > image.Height) height = ((float)image.Height / image.Width) * size; else width = ((float)image.Width / image.Height) * size; } var newBitmap = new Bitmap(image, new Size((int)width, (int)height)); if (newBitmap == null) return false; // save the resized png into a memory stream for future use using (MemoryStream memoryStream = new MemoryStream()) { newBitmap.Save(memoryStream, ImageFormat.Png); var iconWriter = new BinaryWriter(output); if (output == null || iconWriter == null) return false; // 0-1 reserved, 0 iconWriter.Write((byte)0); iconWriter.Write((byte)0); // 2-3 image type, 1 = icon, 2 = cursor iconWriter.Write((short)1); // 4-5 number of images iconWriter.Write((short)1); // image entry 1 // 0 image width iconWriter.Write((byte)width); // 1 image height iconWriter.Write((byte)height); // 2 number of colors iconWriter.Write((byte)0); // 3 reserved iconWriter.Write((byte)0); // 4-5 color planes iconWriter.Write((short)0); // 6-7 bits per pixel iconWriter.Write((short)32); // 8-11 size of image data iconWriter.Write((int)memoryStream.Length); // 12-15 offset of image data iconWriter.Write((int)(6 + 16)); // write image data // png data must contain the whole png data file iconWriter.Write(memoryStream.ToArray()); iconWriter.Flush(); } return true; } } public static class ImageExtension { /// /// Returns an Image format. /// public static ImageFormat GetImageFormat(this Image bitmap) { if (bitmap == null || bitmap.RawFormat == null) return null; ImageFormat format = null; if (ImageFormat.Jpeg.Equals(bitmap.RawFormat)) { format = ImageFormat.Jpeg; } else if (ImageFormat.Gif.Equals(bitmap.RawFormat)) { format = ImageFormat.Gif; } else if (ImageFormat.Png.Equals(bitmap.RawFormat)) { format = ImageFormat.Png; } else if (ImageFormat.Emf.Equals(bitmap.RawFormat)) { format = ImageFormat.Emf; } else if (ImageFormat.Icon.Equals(bitmap.RawFormat)) { format = ImageFormat.Icon; } else if (ImageFormat.Tiff.Equals(bitmap.RawFormat)) { format = ImageFormat.Tiff; } else if (ImageFormat.Bmp.Equals(bitmap.RawFormat) || ImageFormat.MemoryBmp.Equals(bitmap.RawFormat)) // MemoryBmp format raises a GDI exception { format = ImageFormat.Bmp; } else if (ImageFormat.Wmf.Equals(bitmap.RawFormat)) { format = ImageFormat.Wmf; } if (format != null) return format; return ImageFormat.Bmp; } } }