C#的位图位数转换程序

可以实现位图的位数转换:8位到24位、8位到32位、24位到8位、24到32位、32位到8位、32位到24位。



主要的转换程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;

namespace BitmapConverter
{
    class NeverBitmap
    {
        struct BitmapFileHeader
        {
            public UInt16 bfType;
            public UInt32 bfSize;
            public UInt16 bfReserved1;
            public UInt16 bfReserved2;
            public UInt32 bfOffBits;
        }

        struct BitmapInfoHeader
        {
            public UInt32 biSize;
            public UInt32 biWidth;
            public UInt32 biHeight;
            public UInt16 biPlanes;
            public UInt16 biBitCount;
            public UInt32 biCompression;
            public UInt32 biSizeImage;
            public UInt32 biXPelsPerMeter;
            public UInt32 biYPelsPerMeter;
            public UInt32 biClrUsed;
            public UInt32 biClrImportant;
        }

        struct RGBQUAD
        {
            public byte rgbBlue;
            public byte rgbGreen;
            public byte rgbRed;
            public byte rgbReserved;
        }

        private string filepath = null;
        private string savepath = null;
        private BitmapFileHeader bfh;
        private BitmapInfoHeader bih;

        public NeverBitmap(string openpath,string savepath)
        {
            this.filepath = openpath;
            this.savepath = savepath;
        }

        private void Save8Bits(Bitmap bmp)
        {
            bfh.bfOffBits = 1078;
            bfh.bfReserved1 = 0;
            bfh.bfReserved2 = 0;
            bfh.bfSize = 14;
            bfh.bfType = 19778;

            bih.biBitCount = 8;
            bih.biClrImportant = 0;
            bih.biClrUsed = 0;
            bih.biCompression = 0;
            bih.biHeight = (uint)bmp.Height;
            bih.biPlanes = 1;
            bih.biSize = 40;
            bih.biSizeImage = (uint)(bmp.Height * ((bmp.Width * 8 + 31) / 32 * 4));
            bih.biWidth = (uint)bmp.Width;
            bih.biXPelsPerMeter = 0;
            bih.biYPelsPerMeter = 0;

            RGBQUAD[] pal = new RGBQUAD[256];
            for (int i = 0; i < 256; i++)
            {
                pal[i].rgbBlue = (byte)i;
                pal[i].rgbGreen = (byte)i;
                pal[i].rgbRed = (byte)i;
                pal[i].rgbReserved = 0;
            }

            FileInfo f = new FileInfo(savepath);
            using (BinaryWriter bw = new BinaryWriter(f.OpenWrite()))
            {
                bw.Write(bfh.bfType);
                bw.Write(bfh.bfSize);
                bw.Write(bfh.bfReserved1);
                bw.Write(bfh.bfReserved2);
                bw.Write(bfh.bfOffBits);

                bw.Write(bih.biSize);
                bw.Write(bih.biWidth);
                bw.Write(bih.biHeight);
                bw.Write(bih.biPlanes);
                bw.Write(bih.biBitCount);
                bw.Write(bih.biCompression);
                bw.Write(bih.biSizeImage);
                bw.Write(bih.biXPelsPerMeter);
                bw.Write(bih.biYPelsPerMeter);
                bw.Write(bih.biClrUsed);
                bw.Write(bih.biClrImportant);

                for (int i = 0; i < 256; i++)
                {
                    bw.Write(pal[i].rgbBlue);
                    bw.Write(pal[i].rgbGreen);
                    bw.Write(pal[i].rgbRed);
                    bw.Write(pal[i].rgbReserved);
                }

                bmp.RotateFlip(RotateFlipType.Rotate180FlipX);
                BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);

                unsafe
                {
                    byte* ptr = (byte*)data.Scan0.ToPointer();
                    byte[] line = new byte[data.Stride];
                    for (int i = 0; i < data.Stride; i++) line[i] = 0;

                    for (int i = 0; i < bmp.Height; i++)
                    {
                        for (int j = 0; j < bmp.Width; j++)
                        {
                            line[j] = *ptr++;
                        }
                        ptr += data.Stride - bmp.Width;
                        bw.Write(line, 0, line.Length);
                    }
                }

                bw.Close();
                bmp.UnlockBits(data);

            }
        }

        public void Bit8To24()
        {
            Bitmap bmp8 = new Bitmap(filepath);
            BitmapData data8 = bmp8.LockBits(new Rectangle(0, 0, bmp8.Width, bmp8.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
            Bitmap bmp24 = new Bitmap(bmp8.Width, bmp8.Height, PixelFormat.Format24bppRgb);
            BitmapData data24 = bmp24.LockBits(new Rectangle(0, 0, bmp24.Width, bmp24.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            unsafe
            {
                byte* ptr8 = (byte*)data8.Scan0.ToPointer();
                byte* ptr24 = (byte*)data24.Scan0.ToPointer();

                for (int i = 0; i < bmp8.Height; i++)
                {
                    for (int j = 0; j < bmp8.Width; j++)
                    {
                        *ptr24++ = *ptr8;
                        *ptr24++ = *ptr8;
                        *ptr24++ = *ptr8++;
                    }
                    ptr8 += data8.Stride - bmp8.Width;
                    ptr24 += data24.Stride - bmp8.Width * 3;
                }
            }

            bmp8.UnlockBits(data8);
            bmp24.UnlockBits(data24);
            bmp24.Save(savepath);
        }

        public void Bit8To32()
        {
            Bitmap bmp8 = new Bitmap(filepath);
            BitmapData data8 = bmp8.LockBits(new Rectangle(0, 0, bmp8.Width, bmp8.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
            Bitmap bmp32 = new Bitmap(bmp8.Width, bmp8.Height, PixelFormat.Format32bppArgb);
            BitmapData data32 = bmp32.LockBits(new Rectangle(0, 0, bmp32.Width, bmp32.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            unsafe
            {
                byte* ptr8 = (byte*)data8.Scan0.ToPointer();
                byte* ptr32 = (byte*)data32.Scan0.ToPointer();

                for (int i = 0; i < bmp8.Height; i++)
                {
                    for (int j = 0; j < bmp8.Width; j++)
                    {
                        *ptr32++ = *ptr8;
                        *ptr32++ = *ptr8;
                        *ptr32++ = *ptr8++;
                        *ptr32++ = 255;
                    }
                    ptr8 += data8.Stride - bmp8.Width;
                    ptr32 += data32.Stride - bmp8.Width * 4;
                }
            }

            bmp8.UnlockBits(data8);
            bmp32.UnlockBits(data32);
            bmp32.Save(savepath);
        }

        public void Bit24To8()
        {
            Bitmap bmp24 = new Bitmap(filepath);
            BitmapData data24 = bmp24.LockBits(new Rectangle(0, 0, bmp24.Width, bmp24.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            Bitmap bmp8 = new Bitmap(bmp24.Width, bmp24.Height, PixelFormat.Format8bppIndexed);
            BitmapData data8 = bmp8.LockBits(new Rectangle(0, 0, bmp8.Width, bmp8.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

            unsafe
            {
                byte* ptr24 = (byte*)data24.Scan0.ToPointer();
                byte* ptr8 = (byte*)data8.Scan0.ToPointer();

                for (int i = 0; i < bmp8.Height; i++)
                {
                    for (int j = 0; j < bmp8.Width; j++)
                    {
                        *ptr8++=(byte)(((int)(*ptr24++)+(int)(*ptr24++)+(int)(*ptr24++))/3);
                    }
                    ptr24 += data24.Stride - bmp8.Width * 3;
                    ptr8 += data8.Stride - bmp8.Width;
                }
            }

            bmp8.UnlockBits(data8);
            bmp24.UnlockBits(data24);
            Save8Bits(bmp8);
        }

        public void Bit32To8()
        {
            Bitmap bmp32 = new Bitmap(filepath);
            BitmapData data32 = bmp32.LockBits(new Rectangle(0, 0, bmp32.Width, bmp32.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            Bitmap bmp8 = new Bitmap(bmp32.Width, bmp32.Height, PixelFormat.Format8bppIndexed);
            BitmapData data8 = bmp8.LockBits(new Rectangle(0, 0, bmp8.Width, bmp8.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

            unsafe
            {
                byte* ptr32 = (byte*)data32.Scan0.ToPointer();
                byte* ptr8 = (byte*)data8.Scan0.ToPointer();
                for (int i = 0; i < bmp8.Height; i++)
                {
                    for (int j = 0; j < bmp8.Width; j++)
                    {
                        *ptr8++ = (byte)(((int)(*ptr32++) + (int)(*ptr32++) + (int)(*ptr32++)) / 3);
                        ptr32++;
                    }
                    ptr32 += data32.Stride - bmp32.Width * 4;
                    ptr8 += data8.Stride - bmp8.Width;
                }
            }

            bmp8.UnlockBits(data8);
            bmp32.UnlockBits(data32);
            Save8Bits(bmp8);
        }

        public void Bit32To24()
        {
            Bitmap bmp32 = new Bitmap(filepath);
            BitmapData data32 = bmp32.LockBits(new Rectangle(0, 0, bmp32.Width, bmp32.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            Bitmap bmp24 = new Bitmap(bmp32.Width, bmp32.Height, PixelFormat.Format24bppRgb);
            BitmapData data24 = bmp24.LockBits(new Rectangle(0, 0, bmp24.Width, bmp24.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            unsafe
            {
                byte* ptr32 = (byte*)data32.Scan0.ToPointer();
                byte* ptr24 = (byte*)data24.Scan0.ToPointer();
                for (int i = 0; i < bmp24.Height; i++)
                {
                    for (int j = 0; j < bmp24.Width; j++)
                    {
                        *ptr24++ = *ptr32++;
                        *ptr24++ = *ptr32++;
                        *ptr24++ = *ptr32++;
                        ptr32++;
                    }
                    ptr24 += data24.Stride - bmp24.Width * 3;
                    ptr32 += data32.Stride - bmp32.Width * 4;
                }
            }

            bmp32.UnlockBits(data32);
            bmp24.UnlockBits(data24);
            bmp24.Save(savepath);
        }

        public void Bit24To32()
        {
            Bitmap bmp24 = new Bitmap(filepath);
            BitmapData data24 = bmp24.LockBits(new Rectangle(0, 0, bmp24.Width, bmp24.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            Bitmap bmp32 = new Bitmap(bmp24.Width, bmp24.Height, PixelFormat.Format32bppArgb);
            BitmapData data32 = bmp32.LockBits(new Rectangle(0, 0, bmp32.Width, bmp32.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            unsafe
            {
                byte* ptr24 = (byte*)data24.Scan0.ToPointer();
                byte* ptr32 = (byte*)data32.Scan0.ToPointer();

                for (int i = 0; i < bmp32.Height; i++)
                {
                    for (int j = 0; j < bmp32.Width; j++)
                    {
                        *ptr32++ = *ptr24++;
                        *ptr32++ = *ptr24++;
                        *ptr32++ = *ptr24++;
                        *ptr32++ = 255;
                    }
                    ptr24 += data24.Stride - bmp24.Width * 3;
                    ptr32 += data32.Stride - bmp32.Width * 4;
                }
            }

            bmp32.UnlockBits(data32);
            bmp24.UnlockBits(data24);
            bmp32.Save(savepath);
        }
    }
}

posted @ 2012-07-02 13:20  追风  阅读(1495)  评论(0)    收藏  举报