microsoft / Win2D

Win2D is an easy-to-use Windows Runtime API for immediate mode 2D graphics rendering with GPU acceleration. It is available to C#, C++ and VB developers writing apps for the Windows Universal Platform (UWP). It utilizes the power of Direct2D, and integrates seamlessly with XAML and CoreWindow.
http://microsoft.github.io/Win2D
Other
1.82k stars 287 forks source link

Is there a way to create a textured brush stroke? #199

Closed kellylawson closed 8 years ago

kellylawson commented 8 years ago

I'm trying to use d2d to create a brush that emulates a paper-like texture (like pencil on paper) for a winrt drawing app. I'd also like to be able to change the color of the brush. I have been trying by creating a ID2D1BitmapBrush1 from a partially transparent paper texture image, but I'm not sure this is the best way to accomplish my goal and I'm not sure how to colorize it.

I just stumbled across this repo and I don't see anything in the samples quite like what I am trying to do but I'm wondering if it would be possible in Win2D since the interface looks considerably simpler.

clandrew commented 8 years ago

Sure, that shouldn't be too difficult in Win2D. For colorizing, Win2D's effect system makes it easy to do. A common way to colorize is by a color multiply. We can make a colorized, textured brush by making a brush with one input set to a color, one input set to a texture, and join them with a BlendEffect with multiply mode.

Here's an example of how to make a colorized, textured semitransparent brush (in C#):

            ColorSourceEffect colorSourceEffect = new ColorSourceEffect();
            colorSourceEffect.Color = Colors.Magenta; // Set tint color here

            BlendEffect blendEffect = new BlendEffect();
            blendEffect.Background = colorSourceEffect;
            blendEffect.Foreground = texture; // Set texture bitmap here
            blendEffect.Mode = BlendEffectMode.Multiply;

            CanvasImageBrush imageBrush = new CanvasImageBrush(sender, blendEffect);
            imageBrush.ExtendX = CanvasEdgeBehavior.Wrap;
            imageBrush.ExtendY = CanvasEdgeBehavior.Wrap;
            imageBrush.SourceRectangle = texture.Bounds;
            imageBrush.Opacity = 0.5f; // For semitransparency

            // ....
            // Use imageBrush to draw

There are other ways to colorize images with Win2D's effect system, depending on what your app needs.

Win2D's APIs wrap Direct2D APIs, so some of this might look familiar, however you may find that this is simpler and less lines of code.

I appreciate your feedback that this might be something missing from our samples, it could be something we can add.

shawnhar commented 8 years ago

I'm curious why the paper texture would be part of the brush, btw? It might be easier to draw the paper texture first covering the entire background, then blend pencil lines over the top of this, using different colors but no texture, and with blending/alpha set up to let some amount of the background paper texture show through.

kellylawson commented 8 years ago

@clandrew That's exactly the kind of thing I was looking for, and does look much more concise than the direct2d code I've been experimenting with. I will test this out tonight.

@shawnhar Great question; I'm new to d2d so I may be trying to apply the concepts the hard way. I appreciate the alternative approach. I'll try that one too, once I'm familiar enough with the API to apply the concepts.

Thanks and keep up the great work!