private void ShowInfos(string fileName) { Bitmap bmp = null; try { string boxText; string bmpText = string.Empty; if (Path.GetExtension(fileName) == ".ico") { Icon icon = new Icon(fileName); bmp = icon.ToBitmap(); icon.Dispose(); } else { bmp = new Bitmap(fileName); if (bmp.RawFormat.Guid == ImageFormat.Bmp.Guid) { //Analyze the Headers BITMAPFILEHEADER fileHeader = new BITMAPFILEHEADER(); BITMAPINFOHEADER infoHeader = new BITMAPINFOHEADER(); FileStream stream = File.OpenRead(fileName); BinaryReader reader = new BinaryReader(stream); fileHeader.bfType = reader.ReadUInt16(); fileHeader.bfSize = reader.ReadUInt32(); fileHeader.bfReserved1 = reader.ReadUInt16(); fileHeader.bfReserved2 = reader.ReadUInt16(); fileHeader.bfOffBits = reader.ReadUInt32(); infoHeader.biSize = reader.ReadUInt32(); infoHeader.biWidth = reader.ReadInt32(); infoHeader.biHeight = reader.ReadInt32(); infoHeader.biPlanes = reader.ReadUInt16(); infoHeader.biBitCount = reader.ReadUInt16(); infoHeader.biCompression = (BitmapCompressionMode)reader.ReadUInt32(); infoHeader.biSizeImage = reader.ReadUInt32(); infoHeader.biXPelsPerMeter = reader.ReadInt32(); infoHeader.biYPelsPerMeter = reader.ReadInt32(); infoHeader.biClrUsed = reader.ReadUInt32(); infoHeader.biClrImportant = reader.ReadUInt32(); reader.Close(); if (infoHeader.biSize == 40) { bmpText = "Bitmap V1 Header"; } else if (infoHeader.biSize == 124) { bmpText = "Bitmap V5 Header"; } else if (infoHeader.biSize == 108) { bmpText = "Bitmap V4 Header"; } else if (infoHeader.biSize == 56) { bmpText = "Bitmap V3 Header"; } else if (infoHeader.biSize == 52) { bmpText = "Bitmap V2 Header"; } bmpText += Environment.NewLine + "Compression: " + infoHeader.biCompression.ToString(); } } int stride; BitmapData data = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.ReadOnly, bmp.PixelFormat); stride = data.Stride; bmp.UnlockBits(data); boxText = string.Format("Width: {0}, Height: {1}" + Environment.NewLine + "PixelFormat: {2}" + Environment.NewLine + "Stride: {3}", bmp.Width, bmp.Height, bmp.PixelFormat, stride); MessageBox.Show(boxText + Environment.NewLine + bmpText, Path.GetFileName(fileName), MessageBoxButtons.OK, MessageBoxIcon.Information); } finally { bmp?.Dispose(); } }
/// <remarks> /// Using Windows DIB Header BITMAPV5INFOHEADER /// DataType: BI_BITFIELDS (3) /// For compatibility with the GDI bitmap formats: /// RGBAX is 8.8.8.8.0 /// Red mask = 0xFF0000 /// Green mask = 0xFF00 /// Blue mask = 0xFF /// Alpha mask = 0xFF000000 /// No Gamma correction /// No Compression /// Encoding 32 bits bitmap to 32 bits file takes ~2.5ms per megapixel /// Forcing 24 bits bitmap to 32 bits file takes ~10.0ms per megapixel /// </remarks> private void Encode32Bpp(Image bmp) { BITMAPFILEHEADER bmpFH = BITMAPFILEHEADER.Create(); BITMAPV5HEADER bmpV5 = BITMAPV5HEADER.Create(); Bitmap bitmap = CastImageToBitmap(bmp); BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); int paddingLength = 0; int rowSize = data.Stride < 0 ? -data.Stride : data.Stride; using (BinaryWriter bw = new BinaryWriter(new FileStream(_path, FileMode.Create))) { // Encodes file header uint rawDataLength; if (bitmap.PixelFormat == PixelFormat.Format24bppRgb) { paddingLength = 4 - ((data.Width * 3) % 4); if (paddingLength == 4) { paddingLength = 0; } rawDataLength = (uint)(((rowSize - paddingLength) * data.Height * 4) / 3); } else { rawDataLength = (uint)(rowSize * data.Height); } bmpFH.bfSize = FileHeaderSize + bmpV5.biSize + rawDataLength; bmpFH.bfOffBits = FileHeaderSize + bmpV5.biSize; //=============== Read just for forced (Padding)=================================== bw.Write(bmpFH.bfType); bw.Write(bmpFH.bfSize); bw.Write(bmpFH.bfReserved1); bw.Write(bmpFH.bfReserved2); bw.Write(bmpFH.bfOffBits); // Encodes DBI Header bmpV5.biWidth = bitmap.Width; bmpV5.biHeight = bitmap.Height; bmpV5.biPlanes = 1; bmpV5.biBitCount = 32; bmpV5.biCompression = BitmapCompressionMode.BI_BITFIELDS; bmpV5.biSizeImage = rawDataLength; bmpV5.biXPelsPerMeter = 0xec4; // (int)Math.Round(bitmap.VerticalResolution * 39.3701); // Pixels per meter bmpV5.biYPelsPerMeter = 0xec4; // (int)Math.Round(bitmap.VerticalResolution * 39.3701); // Pixels per meter bmpV5.biClrUsed = 0; bmpV5.biClrImportant = 0; // Encodes DBI Extra for ARGB bmpV5.biRedMask = 0xff0000; bmpV5.biGreenMask = 0xff00; bmpV5.biBlueMask = 0xff; bmpV5.biAlphaMask = 0xff000000; bmpV5.biCSType = 0x57696e20; //= "Win ", sRGB = 0x73524742; bmpV5.biEndPoints = new byte[36]; bmpV5.biGammaRed = 0; bmpV5.biGammaGreen = 0; bmpV5.biGammaBlue = 0; bmpV5.biIntent = (int)GamutMappingIntent.LCS_GM_IMAGES; bmpV5.biProfileData = 0; bmpV5.biProfileSize = 0; bmpV5.biReserved = 0; bw.Write(bmpV5.biSize); bw.Write(bmpV5.biWidth); bw.Write(bmpV5.biHeight); bw.Write(bmpV5.biPlanes); bw.Write(bmpV5.biBitCount); bw.Write((uint)bmpV5.biCompression); bw.Write(bmpV5.biSizeImage); bw.Write(bmpV5.biXPelsPerMeter); bw.Write(bmpV5.biYPelsPerMeter); bw.Write(bmpV5.biClrUsed); bw.Write(bmpV5.biClrImportant); bw.Write(bmpV5.biRedMask); bw.Write(bmpV5.biGreenMask); bw.Write(bmpV5.biBlueMask); bw.Write(bmpV5.biAlphaMask); bw.Write(bmpV5.biCSType); bw.Write(bmpV5.biEndPoints); bw.Write(bmpV5.biGammaRed); bw.Write(bmpV5.biGammaGreen); bw.Write(bmpV5.biGammaBlue); bw.Write(bmpV5.biIntent); bw.Write(bmpV5.biProfileData); bw.Write(bmpV5.biProfileSize); bw.Write(bmpV5.biReserved); // Encodes image data byte[] rowBytes = new byte[rowSize]; if (bitmap.PixelFormat == PixelFormat.Format24bppRgb) { // Forces 24 bits bitmap to 32 bits file IntPtr ptr = data.Scan0 + ((bmp.Height - 1) * data.Stride); byte[] bytesWithAlpha = new byte[((rowBytes.Length - paddingLength) * 4) / 3]; for (int i = (bmp.Height - 1); i >= 0; i--, ptr -= data.Stride) //for (IntPtr ptr = data.Scan0 + ((bmp.Height - 1) * data.Stride); ptr.ToInt64() >= data.Scan0.ToInt64(); ptr -= data.Stride) { Marshal.Copy(ptr, rowBytes, 0, data.Stride); int index = 0; int num = rowBytes.Length - paddingLength; for (int x = 0; x < num; x++) { bytesWithAlpha[index] = rowBytes[x]; index++; if ((x % 3) == 2) { bytesWithAlpha[index] = ForcedAlpha; index++; } } bw.Write(bytesWithAlpha); } } else { // 32 bits bitmap to 32 bits file IntPtr ptr = data.Scan0 + ((bmp.Height - 1) * data.Stride); for (int i = (bmp.Height - 1); i >= 0; i--, ptr -= data.Stride) //for (IntPtr ptr = data.Scan0 + ((bmp.Height - 1) * data.Stride); ptr.ToInt64() >= data.Scan0.ToInt64(); ptr -= data.Stride) { Marshal.Copy(ptr, rowBytes, 0, rowSize); bw.Write(rowBytes); } } } bitmap.UnlockBits(data); }