先介绍下我的目的:
  1.我打算通过LockBits和Marshal.Copy来读取2图像的每一点的RGB值。
  2.然后对部分点的RGB进行操作(例如半透明吧)
  3.在回写到图像上,获得新的图片。
  我自己试验了下,发现有问题存在---那就是形成新的图像上的2号图像是斜的,why?
  大家先看下我代码,是不是代码有问题?
                     或者是不是读取的RGB有问题。(我试验过对于同一张图像,(用2次)新的图像没有问题。)
部分代码是这样的:
  1:读取RGB:             int height = source.Height;
                int width = source.Width;
                //
                Rectangle rect = new Rectangle(0, 0, width, height);
                System.Drawing.Imaging.BitmapData bitmapd = source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
                IntPtr ip = bitmapd.Scan0;
                byte[] pixelValues = new byte[height * width*3];//这里RGB三个,则×3
                System.Runtime.InteropServices.Marshal.Copy(ip, pixelValues, 0, height * width*3 );                source.UnlockBits(bitmapd);                //RGB中的方向相反。
                R = new int[height, width];
                G = new int[height, width];
                B = new int[height, width];                int ipoint = 0;
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        R[i, j] = Convert.ToInt32(pixelValues[ipoint++]);
                        G[i, j] = Convert.ToInt32(pixelValues[ipoint++]);
                        B[i, j] = Convert.ToInt32(pixelValues[ipoint++]);
                    }
                }
2:回写RGB           int height = aim.Height;
            int width = aim.Width;
            int ipoint = 0;
            byte[] pixelValue2 = new byte[height * width * 3];                        for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {                  
                        pixelValue2[ipoint++] = Convert.ToByte(R[i, j]);
                        pixelValue2[ipoint++] = Convert.ToByte(G[i, j]);
                        pixelValue2[ipoint++] = Convert.ToByte(B[i, j]);
                   
                }
            }            Rectangle rect2 = new Rectangle(0, 0, width, height);
            System.Drawing.Imaging.BitmapData bitmapd2 = aim.LockBits(rect2, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
            IntPtr ip2 = bitmapd2.Scan0;
            //byte[] pixelValues = new byte[height * width * 3];//这里RGB三个,则×3
            System.Runtime.InteropServices.Marshal.Copy(pixelValue2, 0, ip2, height * width * 3);            aim.UnlockBits(bitmapd2);  

解决方案 »

  1.   

    who can help me?
    给我点方向,告诉我哪里出来的问题也好啊。
    我现在怀疑莫非是不是这个方法读取的RGB数据排列有问题?
    我采用getpixel()方法的时候,得到 的RGB值,他们之间好像不同。
    那么,究竟是哪里的问题?详细讲解一下关于LockBits和Marshal.Copy的关系也好啊。。谢谢了先~
      期待中。
      

  2.   

    没大问题。没有全部细看。、
    首先这里byte[]   pixelValues   =   new   byte[height   *   width*3];//要用height * BitmapData.Stride..这里。pixelValue2[ipoint++]  这样能对吗? 一次移动一个字节,不是丢字节了。
      

  3.   

    多谢楼上的指点。
     我明白如下:
     其实在bitmapdata下它宽度其实是stride即大于或者等于图像width的一个数(4的倍数)。
     我错误的根源呢就是: 在2副大小不同的图像上我错误的进行了多余位数的计算,从而产生了错误。
    (是不是这样??)怎么给分啊。楼上给你分。。
      

  4.   

    你从网上找的程序吧 那个挺狂的ustc的程序是错的 看下面这一段才正确
    *号代表 数据 #代表冗余假如7*3的 
    看得明白吗 8就是stride  如果stride刚好等于宽 程序可能是没问题的
    *******#*******#*******#程序具体我没测 你自己看看吧try
                {
                    int iWidth = Source.Width;
                    int iHeight = Source.Height;                Rectangle rect = new Rectangle(0, 0, Source.Width, Source.Height);
                    BitmapData bd = Source.LockBits(rect, ImageLockMode.ReadWrite, Source.PixelFormat);
                    IntPtr iPtr = bd.Scan0;
                    int iBytes = bd.Stride * bd.Height * 4;
                    byte[] PixelValues = new byte[iBytes];
                    System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes);
                    int t = bd.Stride - bd.Width;
                    Source.UnlockBits(bd);                // 注意这个地方图像的两维方向与数组两维的方向是转置的关系
                    R = new int[iHeight, iWidth];
                    G = new int[iHeight, iWidth];
                    B = new int[iHeight, iWidth];
                    int iPoint = 0;
                    for (int i = 0; i < iHeight; i++)
                    {
                        for (int j = 0; j < iWidth; j++)
                        {
                            // 注意,Windows 中三基色的排列顺序是 BGR 而不是 RGB!
                            B[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
                            G[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
                            R[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
                            iPoint++;
                        }
                        iPoint = iPoint + t;
                    }
                    return true;
                }
      

  5.   

    我的那个是 32 rgb 的也没测  rgb 24的是   ,,声明 我没测试try 
                            { 
                                    int   iWidth   =   Source.Width; 
                                    int   iHeight   =   Source.Height;                                 Rectangle   rect   =   new   Rectangle(0,   0,   Source.Width,   Source.Height); 
                                    BitmapData   bd   =   Source.LockBits(rect,   ImageLockMode.ReadWrite,   Source.PixelFormat); 
                                    IntPtr   iPtr   =   bd.Scan0; 
                                    int   iBytes   =   bd.Stride   *   bd.Height   *   3; 
                                    byte[]   PixelValues   =   new   byte[iBytes]; 
                                    System.Runtime.InteropServices.Marshal.Copy(iPtr,   PixelValues,   0,   iBytes); 
                                    int   t   =   bd.Stride   -   bd.Width; 
                                    Source.UnlockBits(bd);                                 //   注意这个地方图像的两维方向与数组两维的方向是转置的关系 
                                    R   =   new   int[iHeight,   iWidth]; 
                                    G   =   new   int[iHeight,   iWidth]; 
                                    B   =   new   int[iHeight,   iWidth]; 
                                    int   iPoint   =   0; 
                                    for   (int   i   =   0;   i   <   iHeight;   i++) 
                                    { 
                                            for   (int   j   =   0;   j   <   iWidth;   j++) 
                                            { 
                                                    //   注意,Windows   中三基色的排列顺序是   BGR   而不是   RGB! 
                                                    B[i,   j]   =   Convert.ToInt32(PixelValues[iPoint++]); 
                                                    G[i,   j]   =   Convert.ToInt32(PixelValues[iPoint++]); 
                                                    R[i,   j]   =   Convert.ToInt32(PixelValues[iPoint++]); 
                                                    
                                            } 
                                            iPoint   =   iPoint   +   t; 
                                    } 
                                    return   true; 
                            }