我的代码主要是先画一个16色彩深度的图片,然后转换为4位色彩深度的图片
在转换的时候用到内存的操作,就是这个地方出了问题,大家帮我看看那地方出错了!!!
先谢谢各位了...
16位色彩图片绘制好了,没有问题
下面是转换的代码: //设置调色板
            PixelFormat pf = PixelFormat.Format4bppIndexed;
            Bitmap bm = new Bitmap(1, 1, pf);
            ColorPalette cp = bm.Palette;//获取调色板
            cp.Entries[0] = Color.FromArgb(255, 255, 0, 0);
            cp.Entries[1] = Color.FromArgb(255, 0, 255, 0);
            cp.Entries[2] = Color.FromArgb(255, 0, 0, 255);
            cp.Entries[3] = Color.FromArgb(0, 255, 255, 255); //将其alpha值修改为0,使背景透明  //---设置调色板            //
            //先绘制16位的图片,再把该图片转化位4位的带索引颜色的图片
            Bitmap image = new Bitmap(32, 32, System.Drawing.Imaging.PixelFormat.Format4bppIndexed);
            image.Palette = cp;
            Bitmap image16 = DrawImage16(AntDirAng,color);//调用写好的方法绘制16位色的图片
            //把绘制好的16位图片转化位4位的图片
            try
            {
                BitmapData bd ;
                BitmapData bd16 ;
                int h = image.Height;
                int w = image.Width;
                System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, h, w);
                unsafe
                {
                    bd = image.LockBits(rect, ImageLockMode.WriteOnly, pf);
                    bd16 = image16.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format16bppRgb555);
                               
                    //用指针操作的位图数据
                    byte* byteimage; //记录位图数据第一个像素的地址
                    byte* byteimage16;
                    if (bd.Stride > 0)
                    { byteimage = (byte*)bd.Scan0.ToPointer(); }
                    else
                    { byteimage = (byte*)bd.Scan0.ToPointer() + bd.Stride * (h - 1); }
                    if (bd16.Stride > 0)
                    { byteimage16 = (byte*)bd16.Scan0.ToPointer(); }
                    else
                    { byteimage16 = (byte*)bd16.Scan0.ToPointer() + bd16.Stride * (h - 1); }                    uint stride = (uint)Math.Abs(bd.Stride);
                    //用一个嵌套循环扫描源图片,进行转化
                    for (int i = 0; i < h; i++)
                    {
                        for (int j = 0; j < w; j++)
                        {
                            //转化公式:0.3R+0.59G+0.11B,
                            float value = 0.11F * byteimage16[i * bd16.Stride + j * 4] + 0.59F * byteimage16[i * bd16.Stride + j * 4 + 1] + 0.3F * byteimage16[
                                i * bd16.Stride + j * 4 + 2];
                            byteimage[i * bd.Stride + j] = (byte)value;
                            
                            //网上的另一种转化方法,直接读取每个像素的颜色分量
                            //Color pixelc;
                            //byte* b4pixel = byteimage + i * stride + j;
                            //pixelc = image16.GetPixel(i, j);
                            //double value = (pixelc.R * 0.299) + (pixelc.G * 0.587) + (pixelc.B * 0.114);
                            //*b4pixel = (byte)(value * 3 / 255 + 0.5);
                        }// end j-width
                    }// end i-height
                    image.UnlockBits(bd);
                    image16.UnlockBits(bd16);
                }
                //end of unsafe
                return image;就是内存操作unsafe中的代码有问题,请大家帮我看看啊,

解决方案 »

  1.   

    System.Drawing 里面封装了所有 GDI+ 的函数,用它们重写一次,要是再出错了,会有非常明确的说明,比这种 unsafe 好得多。
      

  2.   


    public static class BitmapHelper
    {
    [StructLayout(LayoutKind.Sequential)]
    private struct PixelData
    {
    public byte B;
    public byte G;
    public byte R;
    public byte A;
    } public static void SetAlphaChanelValue(Bitmap image, byte value)
    {
    if (image == null)
    throw new ArgumentNullException("image");
    if (image.PixelFormat != PixelFormat.Format32bppArgb)
    throw new ArgumentException("Wrong PixelFormat"); BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
     ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
    unsafe
    {
    PixelData* pPixel = (PixelData*)bitmapData.Scan0;
    for (int i = 0; i < bitmapData.Height; i++)
    {
    for (int j = 0; j < bitmapData.Width; j++)
    {
    pPixel->A = value;
    pPixel++;
    }
    pPixel += bitmapData.Stride - (bitmapData.Width * 4);
    }
    }
    image.UnlockBits(bitmapData);
    }
    }
      

  3.   

    bitmapData.Stride 这个不是象素的部分,所以要跳过