这似乎应该很简单,但我似乎无法找到任何办法。我有一个自定义的WinForms控件,它有一个重写的绘制方法,可以进行一些自定义绘制。
我在内存中有一个Bitmap,而我想做的就是使用HashBrush绘制整个内容,但保留alpha通道,这样位图的透明部分就不会被绘制。
内存中的位图不是简单的形状,因此将其定义为一组路径或任何东西是不可行的。
编辑:为了回应显示代码,paint例程中有很多代码,所以我只包含一个相关的代码片段,这是有问题的方法。从主绘制覆盖中调用此方法。它接受一个黑色透明蒙版图像列表并将它们组合成一个,然后使用ColorMatrix更改它创建的组合图像的颜色,使其可以叠加在背景上。我想要完成的只是能够在其上绘制哈希标记。
private void PaintSurface(PaintEventArgs e, Image imgParent, List<Image> surfImgs, Rectangle destRect, ToothSurfaceMaterial material)
{
using (Bitmap bmp = new Bitmap(imgParent.Width, imgParent.Height,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb))
{
using (Graphics g = Graphics.FromImage(bmp))
{
foreach (Image img in surfImgs)
{
g.DrawImage(img, System.Drawing.Point.Empty);
}
}
ColorMatrix matrix = new ColorMatrix(
new float[][] {
new float[] { 0, 0, 0, 0, 0},
new float[] { 0, 0, 0, 0, 0},
new float[] { 0, 0, 0, 0, 0},
new float[] { 0, 0, 0, 0.7f, 0},
new float[] { material.R / 255.0f,
material.G / 255.0f,
material.B / 255.0f,
0, 1}
});
ImageAttributes imageAttr = new ImageAttributes();
imageAttr.SetColorMatrix(matrix);
Rectangle r = GetSizedRect(imgParent, destRect);
e.Graphics.DrawImage(bmp,
r,
0,
0,
bmp.Width,
bmp.Height,
GraphicsUnit.Pixel, imageAttr);
}
}
答案 0 :(得分:0)
我认为您不需要{em> overkill 的任何ColorMatrix
,您只需要一个ColorMap
,这里的代码可能不符合您的要求,但应该给出你的想法。那是因为我可能不太了解你的问题,如果你有任何问题,请留下一些评论,我会尽力改善答案:
ImageAttributes imgA = new ImageAttributes();
ColorMap cm = new ColorMap();
cm.OldColor = Color.Black
cm.NewColor = Color.FromArgb((byte)(0.7*255), Color.Green);
imgA.SetRemapTable(new ColorMap[] {cm });
GraphicsUnit gu = GraphicsUnit.Pixel;
g.DrawImage(imageToDraw,new Point[]{Point.Empty,
new Point(backImage.Width/2,0),
new Point(0,backImage.Height/2)},
Rectangle.Round(imageToDraw.GetBounds(ref gu)),
GraphicsUnit.Pixel, imgA);
new Point[]
是一个3 Points
的数组,用于定位目标Rectangle。
上面的代码用于在imageToDraw
之上绘制backImage
,并使用{{将Black
的颜色转换为颜色Green
1}}。这就是你想要实现你的代码。
这可能是你想要的,实际上你的代码没有显示你想要的东西,它只显示你现在所拥有的没有实现任何与你的问题有关的东西。我从您问题中的第一个描述中推断出这一点。输入是具有背景颜色的图像(稍后将部分透明)为Opacity = 70%
。现在您想要的输出是一个图像,其中所有非黑色区域都涂有Black
。然后将处理此输出以将HatchBrush
背景变为Black
背景。
partially transparent
答案 1 :(得分:0)
我最终使用的解决方案是以下方法。首先,我将各个蒙版合并为一个,然后创建一个新的Bitmap并使用HatchBrush绘制整个内容,最后遍历蒙版并根据蒙版在新生成的位图上设置alpha值。
private Bitmap GenerateSurface(Image imgParent, List<Image> surfImgs, ToothSurfaceMaterial material)
{
Bitmap mask = new Bitmap(imgParent.Width, imgParent.Height,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
using (Graphics g = Graphics.FromImage(mask))
{
foreach (Image img in surfImgs)
{
g.DrawImage(img, System.Drawing.Point.Empty);
}
}
Bitmap output = new Bitmap(mask.Width, mask.Height,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
using (Graphics g = Graphics.FromImage(output))
{
if (material.HatchStyle != null)
{
HatchBrush hb = new HatchBrush((HatchStyle)material.HatchStyle, material.FgColor, material.BgColor);
g.FillRectangle(hb, new Rectangle(0, 0, output.Width, output.Height));
}
else
{
SolidBrush sb = new SolidBrush(material.FgColor);
g.FillRectangle(sb, new Rectangle(0, 0, output.Width, output.Height));
}
}
var rect = new Rectangle(0, 0, output.Width, output.Height);
var bitsMask = mask.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
var bitsOutput = output.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
int offset = 0;
for (int y = 0; y < mask.Height; y++)
{
byte* ptrMask = (byte*)bitsMask.Scan0 + y * bitsMask.Stride;
byte* ptrOutput = (byte*)bitsOutput.Scan0 + y * bitsOutput.Stride;
for (int x = 0; x < mask.Width; x++)
{
offset = 4 * x + 3;
ptrOutput[offset] = (byte)(ptrMask[offset] * 0.7);
}
}
}
mask.UnlockBits(bitsMask);
output.UnlockBits(bitsOutput);
return output;
}