Reputation: 177
I had a situation to duplicate an image with the help of bitmap data, below is the code i used to do the same, am I wrong anywhere, please help me.. Try drawing this image https://i.sstatic.net/VCSoQ.png in the bmp format
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");
}
Thanks, Suresh
Upvotes: 1
Views: 7208
Reputation: 2305
If you're willing to use P/Invoke, this can be done with a single copy.
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) );
}
Upvotes: 0
Reputation: 177
There is problem in getting the color palette of the image through BitmapData, on replacing the color palette of the new image with the old, we could get the same image.
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");
Upvotes: 2
Reputation: 4458
with the example on http://msdn.microsoft.com/de-de/library/5ey6h79d.aspx you should get it.
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");
}
Upvotes: 1