如何使用BitmapData复制图像

时间:2012-02-28 09:21:38

标签: c#

我有一个情况,在位图数据的帮助下复制图像,下面是我用来做同样的代码,我在任何地方都错了,请帮助我..尝试绘制此图像 bmp格式的http://i.stack.imgur.com/VCSoQ.png

private void button1_Click(object sender, EventArgs e)
{
Bitmap mask = Image.FromFile("../../Data/mask.bmp") as Bitmap;
BitmapData data = mask.LockBits(new Rectangle(0, 0, mask.Width, mask.Height), ImageLockMode.ReadWrite, mask.PixelFormat);
int bytes = Math.Abs(data.Stride) * mask.Height;
byte[] outPut = new byte[bytes];
Marshal.Copy(data.Scan0, outPut, 0, bytes);

Bitmap test = new Bitmap(mask.Width, mask.Height, mask.PixelFormat);
BitmapData testData = test.LockBits(new Rectangle(0, 0, test.Width, test.Height),
ImageLockMode.ReadWrite, test.PixelFormat);
Marshal.Copy(outPut, 0, testData.Scan0, bytes);
test.UnlockBits(testData);
test.Save("test.jpg");
}

谢谢, 苏雷什

3 个答案:

答案 0 :(得分:2)

通过BitmapData获取图像的调色板时出现问题,在用旧图像替换新图像的调色板时,我们可以获得相同的图像。

Bitmap mask = Image.FromFile("../../Data/mask.bmp") as Bitmap;
        BitmapData data = mask.LockBits(new Rectangle(0, 0, (int)mask.PhysicalDimension.Width, (int)mask.PhysicalDimension.Height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
        int bytes = Math.Abs(data.Stride) * mask.Height;            
        byte[] outPut = new byte[bytes];
        Marshal.Copy(data.Scan0, outPut, 0, bytes);
        Marshal.Copy(outPut, 0, data.Scan0, bytes);
        mask.UnlockBits(data);

        Bitmap test = new Bitmap(mask.Width, mask.Height, PixelFormat.Format8bppIndexed);
        test.Palette = mask.Palette;
        BitmapData testData = test.LockBits(new Rectangle(0, 0, mask.Width, mask.Height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
        Marshal.Copy(outPut, 0, testData.Scan0, bytes);
        test.UnlockBits(data);
        test.Save("test.jpg");

答案 1 :(得分:1)

使用http://msdn.microsoft.com/de-de/library/5ey6h79d.aspx上的示例,你应该得到它。

    private void CopyImage()
    {

        // Create a new bitmap.
        Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");

        // Lock the bitmap's bits.  
        Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
        System.Drawing.Imaging.BitmapData bmpData =
            bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
            bmp.PixelFormat);

        // Get the address of the first line.
        IntPtr ptr = bmpData.Scan0;

        // Declare an array to hold the bytes of the bitmap.
        int bytes  = Math.Abs(bmpData.Stride) * bmp.Height;
        byte[] rgbValues = new byte[bytes];

        // Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

        // Set every third value to 255. A 24bpp bitmap will look red.  
        //for (int counter = 2; counter < rgbValues.Length; counter += 3)
        //    rgbValues[counter] = 255;

        // Copy the RGB values back to the bitmap
        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

        // Unlock the bits.
        bmp.UnlockBits(bmpData);

        // Draw the modified image.
        //e.Graphics.DrawImage(bmp, 0, 150);

        bmp.Save("c:\\fakePhotoCopy.jpg");

    }

答案 2 :(得分:0)

如果您愿意使用P / Invoke,可以使用一份副本完成。

class MyClass
{
  [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
  public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);

  Bitmap _frame = null;
  BitmapData _dest = null;

  void Reinit( int width, int height, PixelFormat format )
  {
    if ( _frame != null )
    {
      _frame.Unlock(_dest);
      _frame.Dispose();
    }

    _frame = new Bitmap( width, height, format );
    _dest = _frame.LockBits( new Rectangle( 0, 0, _frame.Width, _frame.Height ), ImageLockMode.ReadWrite, _frame.PixelFormat );
  }

  void CloneBitmapData( BitmapData src )
  {
    if ( _dest == null || _dest.Width != src.Width || _dest.Height != src.Height )
      Reinit( src.Width, src.Height, src.PixelFormat );

    CopyMemory( _dest.Scan0, src.Scan0, (uint)(src.Stride * src.Height) );
  }