c# - GDI+ Compose bitmap with transparency -
i'd rewrite method using graphics.drawimage()
. no matter pixelformat
of bitmaptodrawon
, bitmapdrawn
values (i tried combinations) should typically pixelformat.format32bpprgb
, pixelformat.format32bppargb
(or pixelformat.format32bpppargb
), cannot obtain result.
this compose operation seems pretty obvious me, looks missing something.
private static void composebitmapwithtransparency(bitmap bitmaptodrawon, bitmap bitmapdrawn) { debug.assert(bitmaptodrawon != null); debug.assert(bitmaptodrawon.pixelformat == pixelformat.format32bpprgb); debug.assert(bitmapdrawn != null); debug.assert(bitmapdrawn.pixelformat == pixelformat.format32bppargb); var width = bitmaptodrawon.width; debug.assert(bitmapdrawn.width == width); var height = bitmaptodrawon.height; debug.assert(bitmapdrawn.height == height); var rect = new rectangle(0, 0, width, height); var bitmaptodrawondata = bitmaptodrawon.lockbits( rect, imagelockmode.readwrite, bitmaptodrawon.pixelformat); var bitmapdrawndata = bitmapdrawn.lockbits( rect, imagelockmode.readonly, bitmapdrawn.pixelformat); unsafe { var pbitmaptodrawon = (structpixel*)bitmaptodrawondata.scan0; var pbitmapdrawn = (structpixel*)bitmapdrawndata.scan0; (int y = 0; y < height; y++) { (int x = 0; x < width; x++) { byte r = pbitmaptodrawon->r; byte g = pbitmaptodrawon->g; byte b = pbitmaptodrawon->b; byte rx = pbitmapdrawn->r; byte gx = pbitmapdrawn->g; byte bx = pbitmapdrawn->b; // transparency of bitmapdrawn taken account. byte alphax = pbitmapdrawn->alpha; byte alphaxcomplement = (byte)(255 - alphax); pbitmaptodrawon->r = (byte)((r * alphaxcomplement + rx * alphax) >> 8); pbitmaptodrawon->g = (byte)((g * alphaxcomplement + gx * alphax) >> 8); pbitmaptodrawon->b = (byte)((b * alphaxcomplement + bx * alphax) >> 8); pbitmaptodrawon++; pbitmapdrawn++; } } } bitmapdrawn.unlockbits(bitmapdrawndata); bitmaptodrawon.unlockbits(bitmaptodrawondata); }
the code structpixel
:
[structlayout(layoutkind.explicit)] public struct structpixel { [fieldoffset(0)] public byte b; [fieldoffset(1)] public byte g; [fieldoffset(2)] public byte r; [fieldoffset(3)] public byte alpha; }
Comments
Post a Comment