I'm probably not the best one to explain how alpha blending is done but here's the idea in a nutshell. I get the RGB values of every pixel for the each image and write them to a new bitmap where I manipulate each color information by applying the following formula:
r = ((image1 pixel (red) * alpha level) + (image2 pixel (red) * inverse alpha level)) / 256
b = ((image1 pixel (blue) * alpha level) + (image2 pixel (blue) * inverse alpha level)) / 256
g = ((image1 pixel (green) * alpha level) + (image2 pixel (green) * inverse alpha level)) / 256
unsafe static WriteableBitmap AlphaBlend(BitmapSource image1, BitmapSource image2, int alphaLevel)
{
const int PIXEL_SIZE = 4;
int ialphaLevel = 256 - alphaLevel;
int height = Math.Min(image1.PixelHeight, image2.PixelHeight);
int width = Math.Min(image1.PixelWidth, image2.PixelWidth);
var bitmap = new WriteableBitmap(width, height, image1.DpiX, image1.DpiY, PixelFormats.Bgr32, null);
var bitmap1 = new WriteableBitmap(image1);
var bitmap2 = new WriteableBitmap(image2);
bitmap.Lock();
bitmap1.Lock();
bitmap2.Lock();
var backBuffer = (byte*)bitmap.BackBuffer.ToPointer();
var bitmap1Buffer = (byte*)bitmap1.BackBuffer.ToPointer();
var bitmap2Buffer = (byte*)bitmap2.BackBuffer.ToPointer();
for (int y = 0; y < height; y++)
{
var row = backBuffer + (y * bitmap.BackBufferStride);
var img1Row = bitmap1Buffer + (y * bitmap1.BackBufferStride);
var img2Row = bitmap2Buffer + (y * bitmap2.BackBufferStride);
for (int x = 0; x < width; x++)
for (int i = 0; i < PIXEL_SIZE; i++)
row[x * PIXEL_SIZE + i] = (byte)(((img1Row[x * PIXEL_SIZE + i] * alphaLevel) + (img2Row[x * PIXEL_SIZE + i] * ialphaLevel)) >> 8);
}
bitmap.AddDirtyRect(new Int32Rect(0, 0, width, height));
bitmap2.Unlock();
bitmap1.Unlock();
bitmap.Unlock();
return bitmap;
}
The method above will probably work best if the 2 images are of the same size. I hope you found this information useful.
No comments:
Post a Comment