Best way to "overlay" picture objects on canvas?

I am trying to create a freehand “drawing” layer over top of another image, allowing the user to turn it on/off as needed. I understand how to handle the actual drawing routines, but am a bit confused about how to create a transparent “picture” to draw into. My thought was that I would have two picture objects, one for the background and one for the “drawing” layer. Two thoughts on how to do this have crossed my mind, I’m just trying to get feedback on the most logical (and CPU efficient) method:

  1. The canvas paint event would first draw the background picture and then (optionally) the drawing layer picture. But I can’t seem to figure out how to create a “transparent” picture object to draw into (and then “DrawPicture” over the background).

  2. Use the BlendPictures (or possibly BlendPicturesWithMask?) routines in the MBS picture plug-in to blend the two layers together before drawing into the canvas, but then again, I need a transparent picture object to be blending. I could draw into the mask and then blend using the background, a solid color picture and the mask, but this would be limited to only a single color.

I’m sure that I’m missing something simple, but there’s nothing in any of the example files or documentation that I can find which applies. Can someone please point me in the right direction?

Cheers.

-bill k

look at picture.mask or the transparent property

Using a mask would be your best bet.

When the user draws something on the picture… draw the same thing IN BLACK on the mask layer
if you use anything other than black you will get various levels of transparency

If you’re not using it already, try the newer Picture constructor, which takes only Width and Height parameters. The old constructor takes three parameters (Width, Height, and Depth), and it creates an opaque all-white picture by default.

The new constructor may be better suited to your project, because it creates an empty picture that remains transparent except for where you draw things into it. For example, if you put the following in a Canvas’s Paint event:

[code]g.ForeColor = RGB(128,128,128) //Gray
g.FillRect 0,0,g.Width,g.Height

dim p as new Picture(100,100)
p.Graphics.ForeColor = RGB(255,0,0) //Red
p.Graphics.FillOval(0,0,100,100)

g.DrawPicture p,30,30[/code]

It will draw a red circle on top of a gray background. To compare the effects of the two constructors, change the “dim p as new Picture(100,100)” line to “dim p as new Picture(100,100,32)”.

[quote=187004:@Jesse Simko]If you’re not using it already, try the newer Picture constructor, which takes only Width and Height parameters. The old constructor takes three parameters (Width, Height, and Depth), and it creates an opaque all-white picture by default.

The new constructor may be better suited to your project, because it creates an empty picture that remains transparent except for where you draw things into it. For example, if you put the following in a Canvas’s Paint event:

[code]g.ForeColor = RGB(128,128,128) //Gray
g.FillRect 0,0,g.Width,g.Height

dim p as new Picture(100,100)
p.Graphics.ForeColor = RGB(255,0,0) //Red
p.Graphics.FillOval(0,0,100,100)

g.DrawPicture p,30,30[/code]

It will draw a red circle on top of a gray background. To compare the effects of the two constructors, change the “dim p as new Picture(100,100)” line to “dim p as new Picture(100,100,32)”.[/quote]

On PC, it is necessary to turn GDI+ on to use that feature.

It can be done in the inspector, or with this on top of the code :

App.UseGDIPlus = True

So I’ve implemented this technique and it is working perfectly on both Mac and Windows. Thanks Jesse for pointing this out.

I am having no problems drawing into the overlay Picture using various shapes, colors, transparency, etc., but what do I need to do to erase portions of it?

In the example below, I’ve drawn (using line segments) into a picture object sized to match the “background” image canvas. The overlay picture makes use of the new Picture constructor like discussed above, creating a completely transparent picture object. The canvas Paint event then draws the picture over top of the image. Now I’m trying to understand how to “erase” portions of the drawing layer. There’s no “transparent” color that I’m aware of that can be used to “clear” portions of the picture like using an eraser tool. There’s obviously something simple that I’m missing (again).

Cheers.

-bill k

What you need is TWO copies of the original image
To “erase” something from your altered version, “cut” the required portion from one and use DRAWPICTURE to “paste” it.

I am using this techinque to move objects around, when the object “moves” I paste the portion that was “under” the object

@Dave S Dave, I’m not necessarily trying to erase an entire object, I want to provide an eraser tool where the user can use a variable sized “pencil eraser” to erase portions of what they’ve drawn, like the eraser tool in a paint program.

I originally implemented this feature with a mask as you had suggested (using BlendPicturesWithMaskMBS), but this limited the drawing layer to only a single color. This current technique provides everything that I want, I just need to figure out the “eraser” part…

I understand… but if you are attempting to “erase” a “non-solid color” area, you need to know what “should” be there… therefore you need an unaltered version of the background image. If you want to do this in non-rectangular shapes (such as a brush, or spline), then you can set a transparent mask on your main image and draw it over the base image. But regardless of the method, you still need to cache the base image

The background image and the drawing layer are entirely separate picture objects. In the canvas Paint event it first draws the background image (in my case this is a live video frame) and then the drawing layer picture. I think that using a Mask is the correct technique here, but I need to do some additional reading to understand this better.

(Too bad the current documentation is such rubbish. Luckily I still have a copy of the old RB Language Reference, Tutorial and User’s Guide)

OK, so I’ve finally figured this out on my own. The answer actually was to be found in an obscure reference in the Picture.Constructor (new method) help page. Nowhere else in the entire documentation is this information even mentioned!

[quote]When this constructor is used, the Picture defaults to translucent and can be returned to that state using ClearRect().
[/quote]

Using Picture.Graphics.ClearRect in the MouseDrag event of the canvas works just fine. The ClearRect help page contains only one line, and doesn’t even mention it’s implications when used with a picture declared using the new Constructor method (with no depth parameter). I’ll say it again, the new style of help documentation is awful. Whoever decided that a Wiki was the way to document something as complex as a programming language was only considering the amount of effort need to build the documentation, not how functional it would be.