Page 1 of 1

Clearing a vector image to transparent

Posted: Fri Sep 20, 2019 12:15 am
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

Re: Clearing a vector image to transparent

Posted: Fri Sep 20, 2019 1:34 am
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

Re: Clearing a vector image to transparent

Posted: Fri Sep 20, 2019 2:16 am
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.

Re: Clearing a vector image to transparent

Posted: Fri Sep 20, 2019 2:29 am
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

Re: Clearing a vector image to transparent

Posted: Fri Sep 20, 2019 8:39 am
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()

Re: Clearing a vector image to transparent

Posted: Fri Sep 20, 2019 8:56 am
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.

Re: Clearing a vector image to transparent

Posted: Fri Sep 20, 2019 12:47 pm
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