问题
I am looking to draw a string on a DC (Graphics - I am using C#) - but I want the drawn text to be "deleted" from the image so that what's left is essentially a cut-out of the text.
If I was to DrawString with a transparent brush obviously nothing would have happened.
Is there a way of drawing something like that, or do I need to use 2 DCs and BitBlt with some combination of NOTs or XOR or whatever (I did similar things years ago, but was wondering if there's an easiery way)?
回答1:
You could set Graphics.CompositingMode
to CompositingMode.SourceCopy
- but I'm not sure if that will work with transparent content.
The way around this is to:
- Draw your text to a separate image using red brush over black background.
- Iterate over each pixel of text image and target image...
- ...manually set target image pixel color's Alpha value according to text's image Red component.
If speed is not a concern and you deal with small bitmaps, you can use GetPixel
and SetPixel
methods. But I would recommend using LockBits
to access BitmapData
directly and process pixels in a byte array. This is fast and not-so-hard-to-implement solution, although you'll have to deal with "unsafe" code (or use the Marshal
class).
LockBits reference on MSDN
Marshal reference on MSDN
回答2:
If you want to cut sth out of the image, you can do it like this:
Drawing2D.GraphicsContainer c = graphics.BeginContainer();
GraphicsPath p = new GraphicsPath();
p.AddString(...);
graphics.SetClip(p, CombineMode.Xor);
graphics.DrawImage(this.Image, this.Location);
graphics.EndContainer(c);
It's like the solution farther above, but first without SetClip the Graphics-Object doesn't get updated, and second, you need to use Xor.
Note, that making a GraphicsContainer is optional, but makes encapsulation easier, especially if you work with transforms.
回答3:
You might want to try:
// g is your Graphics object
using (var path = new GraphicsPath())
{
path.AddString(.... );
g.Clip.Exclude(path);
}
// Do your other painting here
Sounds like this may require you to make a new image and draw the old one on top. I'm not to sure of your situation though.
回答4:
From a quick search it unfortunately doesn't look like System.Drawing supports XOR drawing and you need to use unmanaged calls to GDI+. This answer to a similar question links to a page that might explain how to do that - the interesting file is here.
Hope this helps.
来源:https://stackoverflow.com/questions/6132487/drawing-transparent-text-via-c-sharp-graphics-but-in-a-way-that-it-turns-the