我正在VS2010中编写C#代码来实现以下目标。
我正在尝试在透明位图上绘制文本并运行丑陋的文本。 下面是三个文本的图片(即A,B和C)
注意:A和C有透明背景,B有白色作为背景。 问题:
答:我有一个ARGB像素格式的位图。我想在其中绘制一个文本。绘制的文字具有锋利的边缘,并且不尊重透明度。
B:我写的是完全相同的代码,但与A的不同之处在于位图中的像素不再是透明的。 (我将填写一个矩形)。但如果您不注意文本的像素,您将看到黑色(文本颜色)和白色(背景颜色)的平滑混合。
C:当我将文本绘制到具有透明像素的位图上时,这就是我期待文本的外观。
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void UserControl1_Paint(object sender, PaintEventArgs e)
{
//e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(0, Color.Red)), e.ClipRectangle);
e.Graphics.DrawString("0123456789", new Font("Verdana", 20), Brushes.Red, new PointF(5, 10));
e.Graphics.DrawEllipse(Pens.Black, e.ClipRectangle);
}
// This is a public method, using which I want to save my usercontrol to an image to save to file later.
public Image ToImage(Size size, PixelFormat p)
{
Bitmap b = new Bitmap(Width, Height, p);
using (Graphics g = Graphics.FromImage(b))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
PaintEventArgs e = new PaintEventArgs(g, new Rectangle(0, 0, size.Width, size.Height));
base.OnPaint(e);
this.OnPaint(e);
}
return b;
}
如何使用透明背景使A看起来像C.我很确定这可以做到,因为像photoshop,paint.net这样的软件处理得非常好。
非常感谢!
Datte
答案 0 :(得分:2)
绘制文本不会影响目标位图上的Alpha通道,如果您绘制到要混合到其他位图的中间ARGB位图,它将始终如此。
您需要在绘制文本后操纵位图的像素,因此您需要为每个像素重新计算Alpha值,使其等于您的灰度文本。在遍历位图(慢)或代码的GetPixel
部分时(不安全,指针,快速),您可以使用PutPixel
/ unsafe
组合执行此操作。
答案 1 :(得分:1)
您使用的Graphics对象是什么SmoothingMode? p>
如果您尚未设置,请尝试更改其值:
http://msdn.microsoft.com/en-us/library/system.drawing.graphics.smoothingmode.aspx
答案 2 :(得分:1)
看起来GDI +不支持开箱即用。您可以做的是在白色背景上渲染黑色文本,然后修改像素数据,将所有像素转换为黑色,并使用基于原始亮度的Alpha值。
static void GrayscaleToAlpha(Bitmap image) {
var lockData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
unsafe {
// Pointer to the current pixel
uint* pPixel = (uint*)lockData.Scan0;
// Pointer value at which we terminate the loop (end of pixel data)
var pLastPixel = pPixel + image.Width * image.Height;
while (pPixel < pLastPixel) {
// Get pixel data
uint pixelValue = *pPixel;
// Average RGB
uint brightness = ((pixelValue & 0xFF) + ((pixelValue >> 8) & 0xFF) + ((pixelValue >> 16) & 0xFF)) / 3;
// Use brightness for alpha value, leave R, G, and B zero (black)
pixelValue = (255 - brightness) << 24;
// Copy back to image
*pPixel = pixelValue;
// Next pixel
pPixel++;
}
}
image.UnlockBits(lockData);
}