I need to perform a Graphics.DrawImage
from a source to a target image, ideally from a smaller tile to a larger poster, but it doesn't matter in the specific scenario.
I write into an empty target image, and I set the g.CompositingMode = CompositingMode.SourceCopy
; however, after the writing process, I get wrong values if the source image has an alpha channel.
I already checked for similar question and answers, but none could solve this situation.
There is not a single alpha value for all the source image; the expected result is an exact copy of the source image at the specified location of the target one.
The sample I assembled in order to test this is the following:
// Create a new bitmap.
const int bitmapSize = 5;
Bitmap
bmp = new Bitmap(bitmapSize, bitmapSize, PixelFormat.Format32bppArgb),
bmpDestDrawImage = new Bitmap(bitmapSize, bitmapSize, PixelFormat.Format32bppArgb);
#region create source image
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bitmapSize, bitmapSize);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.WriteOnly, 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];
Random rnd= new Random(0);
for (int counter = 0; counter < rgbValues.Length; /**/)
{
rgbValues[counter++] = (byte)rnd.Next(0,255);
rgbValues[counter++] = (byte)rnd.Next(0, 255);
rgbValues[counter++] = (byte)rnd.Next(0, 255);
rgbValues[counter++] = (byte)rnd.Next(0, 255);
}
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
// Unlock the bits.
bmp.UnlockBits(bmpData);
#endregion
using (Graphics g = Graphics.FromImage(bmpDestDrawImage))
{
// From the Graphics.CompositingMode Property documentation page
g.CompositingMode = CompositingMode.SourceCopy;
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
g.DrawImage(bmp, new Rectangle(0, 0, bitmapSize, bitmapSize), 0, 0, bitmapSize, bitmapSize, GraphicsUnit.Pixel);
}
for (var i = 0; i < bitmapSize; i++)
{
for (var j = 0; j < bitmapSize; j++)
{
Color orig = bmp.GetPixel(i, j);
Color cDrawImage = bmpDestDrawImage.GetPixel(i, j);
Color examined = cDrawImage;
if (orig.R != examined.R || orig.G != examined.G || orig.B != examined.B || orig.A != examined.A)
{
// My expected result is an exact copy of the source image, so I'm not expecting this
throw new Exception("Unexpected.");
}
}
}