GDI +错误:抗锯齿白色透明度 [英] GDI+ Bug: Anti-Aliasing White On Transparency
问题描述
下面的代码将创建一个透明位图,然后画一个白色的椭圆上抗锯齿。
The following code will create a transparent bitmap and then draw a white ellipse on it with anti-aliasing.
using(var background = new Bitmap(500, 500))
using (var graphics = Graphics.FromImage(background))
{
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.Clear(Color.Transparent);
graphics.DrawEllipse(new Pen(Color.White, 50), 250, 250, 150, 150);
background.Save("test.png", ImageFormat.Png);
}
我发现这个bug是周围的边缘反锯齿像素椭圆有意外的颜色。它们具有的(254254254)的RGB值,而不是(255,255,255)。由于GDI +定义为ARGB(0255255255)透明和白(255255255255)为什么我勾兑后看到254?
The bug I have found is that the anti-aliased pixels around the edge of the ellipse have an unexpected color. They have RGB values of (254,254,254) instead of (255,255,255). Since GDI+ defines transparent as ARGB (0,255,255,255) and white as (255,255,255,255) why am i seeing 254 after blending?
推荐答案
我有当我生成的PNG从SVGs单声道键(Mac OS X),但由于某种原因不能在Windows同样的问题。
I had the same problem when I generated PNGs from SVGs in Mono (Mac OS X), but for some reason not on Windows.
要解决这个问题,我从抄最近的RGB值上图的反锯齿像素,但keept抗伪-α值
To fix this i copied the nearest rgb values from the figure to the antialias-pixels, but keept the antialias-alpha value.
中的代码是基于例如,从:的 https://msdn.microsoft.com/en-us/library/ms229672(v = VS。 90)的.aspx
The code is based on the example from: https://msdn.microsoft.com/en-us/library/ms229672(v=vs.90).aspx
代码运行保存方法之前作为最后一步:
Code to run as last step before the save method:
var pxf = PixelFormat.Format32bppArgb;
var rect = new Rectangle(0, 0, image.Width, image.Height);
BitmapData bmpData = image.LockBits(rect, ImageLockMode.ReadWrite, pxf);
IntPtr ptr = bmpData.Scan0;
int numBytes = image.Width * image.Height * 4;
byte[] rgbValues = new byte[numBytes];
Marshal.Copy(ptr, rgbValues, 0, numBytes);
for (int argb = 0; argb < rgbValues.Length; argb += 4) {
var a = rgbValues [argb + 3]; //A
if(a > 0x00 && a < 0xFF) { //Antialiasing:
//Scan for neares solid with 0 transparency:
for (int i = 0; i < 3; i++) { //3 pixels scan seems to be enough
var right = argb + i * 4;
var left = argb - i * 4;
var up = argb - i * image.Width * 4;
var down = argb + i * image.Width * 4;
if (right < rgbValues.Length && rgbValues [right + 3] == 0xFF) {
rgbValues [argb+2] = rgbValues [right + 2]; //R
rgbValues [argb+1] = rgbValues [right + 1]; //G
rgbValues [argb] = rgbValues [right]; //B
break;
} else if (left > 0 && rgbValues [left + 3] == 0xFF) {
rgbValues [argb+2] = rgbValues [left + 2];
rgbValues [argb+1] = rgbValues [left + 1];
rgbValues [argb] = rgbValues [left];
break;
} else if (up > 0 && rgbValues [up + 3] == 0xFF) {
rgbValues [argb+2] = rgbValues [up + 2];
rgbValues [argb+1] = rgbValues [up + 1];
rgbValues [argb] = rgbValues [up];
break;
} else if (down < rgbValues.Length && rgbValues [down + 3] == 0xFF) {
rgbValues [argb+2] = rgbValues [down + 2];
rgbValues [argb+1] = rgbValues [down + 1];
rgbValues [argb] = rgbValues [down];
break;
}
}
//rgbValues [argb+3] = a; //Keep old alpha.
}
}
Marshal.Copy(rgbValues, 0, ptr, numBytes);
image.UnlockBits(bmpData);
`
`
这篇关于GDI +错误:抗锯齿白色透明度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!