/// <summary> /// Load a Bitmap (with transparency) from file (*.bmp or *.png) via file content or Bitmap ctor /// </summary> /// <param name="fileName"></param> /// <param name="highContrast"></param> /// <returns>The Bitmap with fully transparency if available</returns> public static Bitmap BitmapFromFile(string fileName, bool highContrast = false) { Bitmap bitmap = null; if (string.IsNullOrEmpty(fileName)) { throw new ArgumentNullException(nameof(fileName)); } if (!File.Exists(fileName)) { throw new ArgumentException("File does not exist", nameof(fileName)); } byte[] bytes = IsBmpFile(fileName); if (!highContrast && bytes != null) { int offBits = BitConverter.ToInt32(bytes, 10); //normally 54 int width = BitConverter.ToInt32(bytes, 18); int height = BitConverter.ToInt32(bytes, 22); int length = BitConverter.ToInt16(bytes, 2) - offBits; NativeMethods.BitmapCompressionMode compression = (NativeMethods.BitmapCompressionMode)BitConverter.ToUInt32(bytes, 30); short bitCount = BitConverter.ToInt16(bytes, 28); //Make some tests if it is a ARGB Bitmap if (bitCount == 32 && compression == NativeMethods.BitmapCompressionMode.BI_RGB) { GCHandle gcH = GCHandle.Alloc(bytes, GCHandleType.Pinned); IntPtr scan0 = gcH.AddrOfPinnedObject() + offBits; bitmap = new Bitmap(width, height, 4 * width, PixelFormat.Format32bppArgb, scan0); if (height > 0) { bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); } gcH.Free(); return(bitmap); } } //What shall we do with .png files or .bmp files with smaller formats ? bitmap = new Bitmap(fileName); if (!highContrast) { if (!(bitmap.PixelFormat == PixelFormat.Format32bppArgb || bitmap.PixelFormat == PixelFormat.Format32bppPArgb)) { bitmap.MakeTransparent(bitmap.GetPixel(0, 0)); } else { if ((int)bitmap.HorizontalResolution != 96) { bitmap.SetResolution(96.0f, 96.0f); //only png bitmaps can have other resolution } } } return(bitmap); }
public static Bitmap BitmapFromFile(string fileName, bool highContrast = false) { Bitmap bitmap = null; if (!highContrast && !Path.GetExtension(fileName).Equals(".PNG", StringComparison.OrdinalIgnoreCase)) { byte[] bytes = File.ReadAllBytes(fileName); string headerMark = Encoding.ASCII.GetString(bytes, 0, 2); if (headerMark.Equals("BM")) { int offBits = BitConverter.ToInt32(bytes, 10); //normally 54 int width = BitConverter.ToInt32(bytes, 18); int height = BitConverter.ToInt32(bytes, 22); int length = BitConverter.ToInt16(bytes, 2) - offBits; NativeMethods.BitmapCompressionMode compression = (NativeMethods.BitmapCompressionMode)BitConverter.ToUInt32(bytes, 30); short bitCount = BitConverter.ToInt16(bytes, 28); //Make some tests if it is a ARGB Bitmap if (bitCount == 32 && compression == NativeMethods.BitmapCompressionMode.BI_RGB) { GCHandle gcH = GCHandle.Alloc(bytes, GCHandleType.Pinned); IntPtr scan0 = gcH.AddrOfPinnedObject() + offBits; bitmap = new Bitmap(width, height, 4 * width, PixelFormat.Format32bppArgb, scan0); if (height > 0) { bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); } gcH.Free(); //scan0 is copied to other location, we can test it here //BitmapData data = bitmap.LockBits(new Rectangle(new Point(), bitmap.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); //IntPtr ptr = data.Scan0; //bitmap.UnlockBits(data); return(bitmap); } } } //What shall we do with .png files or .bmp files with smaller formats ? bitmap = new Bitmap(fileName); if (!highContrast) { if (!(bitmap.PixelFormat == PixelFormat.Format32bppArgb || bitmap.PixelFormat == PixelFormat.Format32bppPArgb)) { bitmap.MakeTransparent(bitmap.GetPixel(0, 0)); } else { if ((int)bitmap.HorizontalResolution != 96) { bitmap.SetResolution(96.0f, 96.0f); //only png bitmaps can have other resolution } } } return(bitmap); }