예제 #1
0
        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();
            }
        }
예제 #2
0
        /// <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);
        }