Clearing a vector image to transparent

Just starting out? Need help? Post your questions and find answers here.
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Clearing a vector image to transparent

Post by Samuel »

I'm trying to wide clean a transparent image that is used for vector drawing. With a regular image output you can use FillMemory() or DrawingMode(#PB_2DDrawing_AlphaChannel) to wipe the image clean. I have yet to find a similar command for vector images.
I've tried FillVectorOutput(), but that doesn't work if you're trying to wipe clean an image back to it's transparent state.
Any help is appreciated.

Code: Select all

EnableExplicit

Declare UpdateMouse(ImageHandle.l, MouseX.l, MouseY.l)

Define.l Event
Define.l Image

Global.l Font
Global.l WinH = 600
Global.l WinW = 800

Font = LoadFont(#PB_Any, "Arial", 14)

If OpenWindow(0, 0, 0, WinW, WinH, "Vector Drawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, WinW, WinH)
  
  Image = CreateImage(#PB_Any, WinW, WinH, 32, #PB_Image_Transparent)
  
  Repeat
    Event = WaitWindowEvent(32)
    
    UpdateMouse(Image, WindowMouseX(0), WindowMouseY(0))
    
  Until Event = #PB_Event_CloseWindow
EndIf

Procedure UpdateMouse(ImageHandle.l, MouseX.l, MouseY.l)
  
  ;Update Image With New Mouse Coordinates.
  StartVectorDrawing(ImageVectorOutput(ImageHandle))
    ;####
    ;Doesn't work for clearing the image back to it's original transparency.
    ;VectorSourceColor(RGBA(0,0,0,0))
    ;FillVectorOutput()
    ;####

    VectorSourceColor(RGBA(255,128,0,255))
    VectorFont(FontID(Font), 50)
    
    MovePathCursor(20, 20)
    DrawVectorText("MX: " + Str(MouseX) + " MY: " + Str(MouseY))
  StopVectorDrawing()
  
  ;Draw To Canvas.
  StartDrawing(CanvasOutput(0))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    Box(0, 0, WinW, WinH, RGBA(40,50,60,255))
    DrawAlphaImage(ImageID(ImageHandle), 0, 0)
  StopDrawing()
  
EndProcedure
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Clearing a vector image to transparent

Post by RASHAD »

Hi

Code: Select all

EnableExplicit
Declare UpdateMouse(ImageHandle.l, MouseX.l, MouseY.l)

Define.l Event
Define.l Image

Global.l Font
Global.l WinH = 600
Global.l WinW = 800

Font = LoadFont(#PB_Any, "Arial", 14)

If OpenWindow(0, 0, 0, WinW, WinH, "Vector Drawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, WinW, WinH)
 
  Image = CreateImage(#PB_Any, WinW, WinH, 32, #PB_Image_Transparent)
 
  Repeat
    Event = WaitWindowEvent(32)
   
    UpdateMouse(Image, WindowMouseX(0), WindowMouseY(0))
   
  Until Event = #PB_Event_CloseWindow
EndIf

Procedure UpdateMouse(ImageHandle.l, MouseX.l, MouseY.l)

  ;Update Image With New Mouse Coordinates.
  StartVectorDrawing(ImageVectorOutput(ImageHandle))
   StartDrawing(ImageOutput(ImageHandle))
    DrawingMode(#PB_2DDrawing_AlphaChannel )
    Box(0, 0, WinW, WinH, RGBA(0,0,0,0))
   StopDrawing()
    
    VectorSourceColor(RGBA(255,128,0,255))
    VectorFont(FontID(Font), 50)
   
    MovePathCursor(20, 20)
    DrawVectorText("MX: " + Str(MouseX) + " MY: " + Str(MouseY))
  StopVectorDrawing()
 
  ;Draw To Canvas.
  StartDrawing(CanvasOutput(0))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    Box(0, 0, WinW, WinH, RGBA(40,50,60,255))
    DrawAlphaImage(ImageID(ImageHandle), 0, 0)
  StopDrawing()
 
EndProcedure

Code: Select all

EnableExplicit
Declare UpdateMouse(ImageHandle.l, MouseX.l, MouseY.l)

Define.l Event
Define.l Image,image2

Global.l Font
Global.l WinH = 600
Global.l WinW = 800

Font = LoadFont(#PB_Any, "Arial", 14)

If OpenWindow(0, 0, 0, WinW, WinH, "Vector Drawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, WinW, WinH)
 
  Image = CreateImage(#PB_Any, WinW, WinH, 32, #PB_Image_Transparent)
 
  Repeat
    Event = WaitWindowEvent(32)
    CopyImage(image,image2)
    UpdateMouse(Image2, WindowMouseX(0), WindowMouseY(0))
   
  Until Event = #PB_Event_CloseWindow
EndIf

Procedure UpdateMouse(ImageHandle.l, MouseX.l, MouseY.l)
  ;Update Image With New Mouse Coordinates.
  StartVectorDrawing(ImageVectorOutput(ImageHandle))
     
    VectorSourceColor(RGBA(255,128,0,255))
    VectorFont(FontID(Font), 50)
   
    MovePathCursor(20, 20)
    DrawVectorText("MX: " + Str(MouseX) + " MY: " + Str(MouseY))
  StopVectorDrawing()
 
  ;Draw To Canvas.
  StartDrawing(CanvasOutput(0))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    Box(0, 0, WinW, WinH, RGBA(40,50,60,255))
    DrawAlphaImage(ImageID(ImageHandle), 0, 0)
  StopDrawing()
 
EndProcedure
Egypt my love
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Clearing a vector image to transparent

Post by Samuel »

Interesting and thank you, I didn't know that you could nest drawing outputs. That works for my testing example.
The strange thing is that when I implemented it into my larger program. I started getting artifacts around the text when I change the text's colors, even though the image was being completely cleared in between the color change. For example when white text changed to red text I could still see some white pixels around the red text.
I fixed it by filling the image completely black before clearing it with DrawingMode(#PB_2DDrawing_AlphaChannel) like so.

Code: Select all

  StartVectorDrawing(ImageVectorOutput(ImageHandle))
    StartDrawing(ImageOutput(ImageHandle))
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      Box(0, 0, WinW, WinH, RGBA(0,0,0,255))
      DrawingMode(#PB_2DDrawing_AlphaChannel )
      Box(0, 0, WinW, WinH, RGBA(0,0,0,0))
    StopDrawing()
   
    VectorSourceColor(RGBA(255,128,0,255))
    VectorFont(FontID(Font), 50)
   
    MovePathCursor(20, 20)
    DrawVectorText("MX: " + Str(MouseX) + " MY: " + Str(MouseY))
  StopVectorDrawing()
I can't replicate the text artifacts in a smaller example, yet. But I plan on looking into it further to try and find out why it's happening. If I can duplicate the problem in a smaller example I'll post it.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Clearing a vector image to transparent

Post by RASHAD »

I noticed that most of the time there is a problem with Pure Black & Pure White
So usually I use RGBA(1,0,0,255) or similar
Egypt my love
#NULL
Addict
Addict
Posts: 1497
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Clearing a vector image to transparent

Post by #NULL »

There is no AllChannels flag for vector drawing, it's always blended in some way. So if you use VectorSourceColor(RGBA(0,0,0,0)) it will effectively do nothing :) . You can overwrite all channel values with FillVectorOutput() if you use a VectorSourceColor() with alpha 255, but any lower alpha value will result in a blend with what is already there, if my observations are correct. With the 2D drawing lib you can just Box() with AllChannels and the current values will be replaced, even the alpha channel with any value.

You can use a normal 2d drawing block with Box() and AllChannels before the vector drawing block to ensure a definitve background setup. But It's not clear to me what you want to do. Why do you want to DrawAlphaImage()? Is it just to blend with the Box()-background? In that case I think the canvas drawing should look like this:

Code: Select all

  StartDrawing(CanvasOutput(0))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Box(0, 0, WinW, WinH, RGBA(40,150,60,255))
    DrawingMode(#PB_2DDrawing_AllChannels | #PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(ImageHandle), 0, 0)
  StopDrawing()
#NULL
Addict
Addict
Posts: 1497
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Clearing a vector image to transparent

Post by #NULL »

Samuel wrote:

Code: Select all

      ...
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      Box(0, 0, WinW, WinH, RGBA(0,0,0,255))
      DrawingMode(#PB_2DDrawing_AlphaChannel )
      Box(0, 0, WinW, WinH, RGBA(0,0,0,0))
      ...
   
    VectorSourceColor(RGBA(255,128,0,255))
  StopVectorDrawing()
I can't replicate the text artifacts in a smaller example, yet. But I plan on looking into it further to try and find out why it's happening. If I can duplicate the problem in a smaller example I'll post it.
I did not experiment with this, but from my understanding what is happening is the following:
You are just blending opaque black with what is already there, which can result in anything. Then you reset only the alpha channel to zero, so you have transparent random colors anywhere. Then you draw (i.e. blend) text with the vector lib with alpha 255, so inside the text it will more or less replace the color, but on the edges the antialiasing will result in a lower alpha value of the drawn text, so it blends with the 'transparent random pixels' underneath, raising their existing alpha value so they become visible.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Clearing a vector image to transparent

Post by RASHAD »

Hi Samuel
Notes for any counter :
- Use Monospace type Font (Consolas for ex.)
- Add required "0" to left

Code: Select all

EnableExplicit
Declare UpdateMouse(ImageHandle.l, MouseX.l, MouseY.l)

Define.l Event
Define.l Image

Global.l Font
Global.l WinH = 600
Global.l WinW = 800

Font = LoadFont(#PB_Any, "Consolas", 14)

If OpenWindow(0, 0, 0, WinW, WinH, "Vector Drawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, WinW, WinH)
 
  Image = CreateImage(#PB_Any, WinW, WinH, 32, #PB_Image_Transparent)
 
  Repeat
    Event = WaitWindowEvent(32)
   
    UpdateMouse(Image, WindowMouseX(0), WindowMouseY(0))
   
  Until Event = #PB_Event_CloseWindow
EndIf

Procedure UpdateMouse(ImageHandle.l, MouseX.l, MouseY.l)

  ;Update Image With New Mouse Coordinates.
  StartVectorDrawing(ImageVectorOutput(ImageHandle))
   StartDrawing(ImageOutput(ImageHandle))
    DrawingMode(#PB_2DDrawing_AlphaChannel )
    Box(0, 0, WinW, WinH, RGBA(0,0,0,0))
   StopDrawing()
   
    VectorSourceColor(RGBA(255,128,0,255))
    VectorFont(FontID(Font), 50)
   
    MovePathCursor(20, 20)
    If MouseX >= 0
      DrawVectorText("MX: " + RSet(Str(MouseX),3,"0") + " MY: " + RSet(Str(MouseY),3,"0"))
    Else
      DrawVectorText("MX: 000 MY: 000")
    EndIf
  StopVectorDrawing()
 
  ;Draw To Canvas.
  StartDrawing(CanvasOutput(0))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    Box(0, 0, WinW, WinH, RGBA(40,50,60,255))
    DrawAlphaImage(ImageID(ImageHandle), 0, 0)
  StopDrawing()
 
EndProcedure
Egypt my love
Post Reply