[Mono-bugs] [Bug 495516] New: DrawImage and PNGCodec broken w.r.t. alpha channel
bugzilla_noreply at novell.com
bugzilla_noreply at novell.com
Thu Apr 16 10:17:21 EDT 2009
http://bugzilla.novell.com/show_bug.cgi?id=495516
Summary: DrawImage and PNGCodec broken w.r.t. alpha channel
Classification: Mono
Product: Mono: Class Libraries
Version: 2.4.x
Platform: All
OS/Version: All
Status: NEW
Severity: Major
Priority: P5 - None
Component: libgdiplus
AssignedTo: mono-bugs at lists.ximian.com
ReportedBy: alexander.shulgin at yessoftware.com
QAContact: mono-bugs at lists.ximian.com
Found By: ---
Created an attachment (id=286116)
--> (http://bugzilla.novell.com/attachment.cgi?id=286116)
Test image for sample code.
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.8)
Gecko/2009032609 Firefox/3.0.8 (.NET CLR 3.5.30729)
Alpha blending is broken in libgdiplus.
Below is sample code to demonstrate the problem. I create the sample mask: a
linear gradient from LT- to BR-corner with increasing opacity; then I create
the sample background filled with red color.
After I draw the mask over the background I get all white rectangle. Sample
code:
--8<----8<----8<----8<----8<----8<--
using System;
using System.Drawing;
namespace AlphaBlend
{
class MainClass
{
public static void Main(string[] args)
{
Bitmap mask = new Bitmap(128, 128);
using (Graphics g = Graphics.FromImage(mask))
{
for (int y = 0; y < mask.Height; ++y)
for (int x = 0; x < mask.Width; ++x)
mask.SetPixel(x, y, Color.FromArgb(x + y, 255, 255,
255));
}
mask.Save("mask.png");
Bitmap bg = new Bitmap(mask.Width, mask.Height);
using (Graphics g = Graphics.FromImage(bg))
{
using (SolidBrush b = new SolidBrush(Color.Red))
g.FillRectangle(b, Rectangle.FromLTRB(0, 0, bg.Width,
bg.Height));
g.DrawImage(mask, 0, 0);
}
bg.Save("composite.png");
}
}
}
--8<----8<----8<----8<----8<----8<--
Also PNGCodec is broken. If we load a sample ARGB PNG image, then save it
untouched and load again, we get corrupted image data (pre-multiplied twice).
Sample code:
--8<----8<----8<----8<----8<----8<--
using System;
using System.Drawing;
namespace AlphaBlend
{
class MainClass
{
public static void Main(string[] args)
{
Bitmap pngmask = new Bitmap("gimpmask.png");
Console.WriteLine("orig: PixelFormat={0}, pixel at (4,4): {1}",
pngmask.PixelFormat, pngmask.GetPixel(4,4));
pngmask.Save("savedmask.png");
Bitmap loadedmask = new Bitmap("savedmask.png");
Console.WriteLine("load: PixelFormat={0}, pixel at (4,4): {1}",
loadedmask.PixelFormat,
loadedmask.GetPixel(4,4));
}
}
}
--8<----8<----8<----8<----8<----8<--
On the attached test image (gimpmask.png) this code gives:
orig: PixelFormat=Format32bppArgb, pixel at (4,4): Color [A=51, R=49, G=49,
B=49]
load: PixelFormat=Format32bppArgb, pixel at (4,4): Color [A=51, R=9, G=9, B=9]
Proposed solution:
1. Postpone pre-multiplication until actual use of cairo functions which
require it.
2. Add pre-multiplication code where it's currently missing.
3. Add code to handle saving of PARGB bitmaps created by user like this: new
Bitmap(w, h, PixelFormat.Format32bppPArgb). Possibly just throw
NotImplementedException for now.
This way we'll fix current problem with creating mask in memory and alpha
blending it on some background.
We'll avoid post-multiplication otherwise needed before saving an ARGB PNG
image. Also, libgdiplus won't lie anymore that loaded image data is in ARGB
format while it's actually in PARGB. :)
I'll try to prepare the patch shortly.
Reproducible: Always
Steps to Reproduce:
1. Run sample code.
Actual Results:
1. For the first test case, the resulting image (composite.png) is all-white.
2. For the second one, image data in memory differs after save/load from disk.
Expected Results:
1. The resulting image should have nice linear gradient from red to white.
2. Image data should not change after save/load from disk of PNG file.
Initial thread in mono-winforms-list:
http://www.nabble.com/DrawImage-alpha-blend-broken-in-libgdiplus-to22931264.html
--
Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.
More information about the mono-bugs
mailing list