Question about DrawingBuffers (with example)

Just starting out? Need help? Post your questions and find answers here.
Josepho
User
User
Posts: 65
Joined: Thu Oct 22, 2020 7:01 am

Question about DrawingBuffers (with example)

Post by Josepho »

Hi im trying to create a function that turns a selected color into a transparent using image buffers, i know how to do it with plot

Code: Select all

            For i = 0 To ImageHeight(imageFiles()\imgBackup\i)-1
              For z = 0 To ImageWidth(imageFiles()\imgBackup\i)-1
                
                If Point(z,i) = cKey
                  Plot(z,i,RGBA(0,0,0,0))
                EndIf
    
              Next z
            Next i
but im having issues trying to do the same using image buffers, here is what i have at this moment using the example of the documentation

Code: Select all

      If StartDrawing(ImageOutput(imageFiles()\imgBackup\i))
          cKey = imageFiles()\ckeys()
          cBlank = RGBA(0,0,0,0)

          If cKey >= 0
            
            Buffer = DrawingBuffer()
            Pitch = DrawingBufferPitch()
            PixelFormat = DrawingBufferPixelFormat()
            
            If PixelFormat = #PB_PixelFormat_32Bits_RGB Or PixelFormat = #PB_PixelFormat_32Bits_BGR
              Offset = 4
            Else ; 24-bit
              Offset = 3
            EndIf
            
            For y = 0 To ImageHeight(imageFiles()\imgBackup\i)-1
              
              *Line.Pixel = Buffer+Pitch*y
              
              For x = 0 To ImageWidth(imageFiles()\imgBackup\i)-1
                
                Debug "data colors: "+Str(x)+" "+Str(y)+" "+Str(*Line\Pixel)+" "+Str(cKey)+" "+Str(cBlank)
                
                If *Line\Pixel = cKey
                  *Line\Pixel = cBlank
                EndIf
                
                *Line+Offset
                
              Next x
            Next y
      endif
      stopDrawing()
What im missing?? The debug is showing negative numbers for the *Line\Pixel why is that? The result doesnt change the image at any way

Many thanks for your help!
Last edited by Josepho on Thu Feb 02, 2023 5:40 pm, edited 1 time in total.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Noob question about imageBuffer function

Post by infratec »

I'm missing a functional example.
Josepho
User
User
Posts: 65
Joined: Thu Oct 22, 2020 7:01 am

Re: Noob question about imageBuffer function

Post by Josepho »

Here is a working example, the commented plot works but the actual code doesnt

Code: Select all

Structure Pixel
  Pixel.l
EndStructure

If OpenWindow(0, 0, 0, 220, 220, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0, 10, 10, 200, 200)
    UsePNGImageDecoder()

    img.i = LoadImage(#PB_Any,"unitytest2.png")
    
    If StartDrawing(ImageOutput(img))
      DrawingMode(#PB_2DDrawing_AllChannels)
      
      cKey = Point(0,0)
      cBlank = RGBA(0,0,0,0)
      
      Buffer = DrawingBuffer()
      Pitch = DrawingBufferPitch()
      PixelFormat = DrawingBufferPixelFormat()
      
      If PixelFormat = #PB_PixelFormat_32Bits_RGB Or PixelFormat = #PB_PixelFormat_32Bits_BGR
        Offset = 4
      Else ; 24-bit
        Offset = 3
      EndIf
      
      For y = 0 To ImageHeight(img)-1
        
        *Line.Pixel = Buffer+Pitch*y
        
        For x = 0 To ImageWidth(img)-1
          
          
          If *Line\Pixel = cKey
            *Line\Pixel = cBlank
          EndIf
          
          *Line+Offset
          
        Next x
      Next y
      
;       For i = 0 To ImageHeight(img)-1
;         For z = 0 To ImageWidth(img)-1
;           
;           If Point(z,i) = cKey
;             Plot(z,i,RGBA(0,0,0,0))
;           EndIf
;           
;         Next z
;       Next i
      
      StopDrawing()
    EndIf
    
    
    If StartDrawing(CanvasOutput(0))
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      DrawImage(ImageID(img),0,0)
      StopDrawing()
    EndIf
    
    Repeat
      Event = WaitWindowEvent()
             
      
    Until Event = #PB_Event_CloseWindow
  EndIf
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Question about DrawingBuffers (with example)

Post by Mijikai »

The problem seems to be the check:

Code: Select all

PixelFormat = #PB_PixelFormat_32Bits_RGB Or PixelFormat = #PB_PixelFormat_32Bits_BGR
DrawingBufferPixelFormat() returns flags so correct would be:

Code: Select all

PixelFormat & #PB_PixelFormat_32Bits_RGB Or PixelFormat & #PB_PixelFormat_32Bits_BGR
Josepho
User
User
Posts: 65
Joined: Thu Oct 22, 2020 7:01 am

Re: Question about DrawingBuffers (with example)

Post by Josepho »

Im afraid that doesnt have any effect Mijikai
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Question about DrawingBuffers (with example)

Post by infratec »

Mijikai is right.

You need the & in the compare.

Your next bug is the color order of the pixel.

And your example i still not executable, because we don't own this image.
Josepho
User
User
Posts: 65
Joined: Thu Oct 22, 2020 7:01 am

Re: Question about DrawingBuffers (with example)

Post by Josepho »

This is the image, the target is to remove the green background

Image
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Question about DrawingBuffers (with example)

Post by infratec »

A working example:

Code: Select all

Structure imgBackup_Structure
  i.i
EndStructure


Structure imageFile_Structure
  imgBackup.imgBackup_Structure
  List ckeys.i()
EndStructure

Structure Pixel
  Pixel.l
EndStructure



NewList imageFiles.imageFile_Structure()

AddElement(imageFiles())
imageFiles()\imgBackup\i = CreateImage(#PB_Any, 200, 200, 32, RGBA($80, $81, $82, $FF))

If StartDrawing(ImageOutput(imageFiles()\imgBackup\i))
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(10, 10, 100, 100, RGBA($20, $30, $40, $FF))
  StopDrawing()
EndIf

AddElement(imageFiles()\ckeys())
imageFiles()\ckeys() = RGBA($20, $30, $40, $FF)



Define *Line.Pixel
Define.i iWidth, iHeight

If StartDrawing(ImageOutput(imageFiles()\imgBackup\i))
  
  DrawingMode(#PB_2DDrawing_AllChannels)
  
  cKey = imageFiles()\ckeys()
  cBlank = RGBA(0, 0, 0, 0)
  
  If cKey <> 0
    
    *Buffer = DrawingBuffer()
    Pitch = DrawingBufferPitch()
    PixelFormat = DrawingBufferPixelFormat()
    
    
    If PixelFormat & #PB_PixelFormat_32Bits_RGB Or PixelFormat & #PB_PixelFormat_32Bits_BGR
      If PixelFormat & #PB_PixelFormat_32Bits_RGB
        Debug "RGB"
      Else
        Debug "BGR"
        cKey = RGBA(Blue(ckey), Green(ckey), Red(ckey), Alpha(ckey))
      EndIf
      Offset = 4
    Else ; 24-bit
      Offset = 3
    EndIf
    
    iHeight = ImageHeight(imageFiles()\imgBackup\i) - 1
    iWidth = ImageWidth(imageFiles()\imgBackup\i) - 1
    
    For y = 0 To iHeight
      
      *Line = *Buffer + Pitch * y
      
      For x = 0 To iWidth
        
        ;Debug Str(*Line) + " " + Str(x) + " " + Str(y) + " " + Hex(*Line\Pixel, #PB_Long) + " " + Hex(cKey, #PB_Long) + " " + Hex(cBlank, #PB_Long)
        
        If *Line\Pixel = cKey
          *Line\Pixel = cBlank
        EndIf
        
        *Line + Offset
        
      Next x
    Next y
  EndIf
  StopDrawing()
EndIf


OpenWindow(0, 0, 0, 200, 200, "Test", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(0, 0, 0, 0, 0, ImageID(imageFiles()\imgBackup\i))


Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Last edited by infratec on Thu Feb 02, 2023 6:26 pm, edited 2 times in total.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Question about DrawingBuffers (with example)

Post by infratec »

And for speed reasons you can also check:

Code: Select all

CustomFilterCallback()
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Question about DrawingBuffers (with example)

Post by Mijikai »

The example wasnt runnable for me but i read through it again and found this: cKey correct would be cKey.l otherwise it will fail on x64
Josepho
User
User
Posts: 65
Joined: Thu Oct 22, 2020 7:01 am

Re: Question about DrawingBuffers (with example)

Post by Josepho »

It works! many thanks, i modified the code to make it work with the image and it works, yes also adding the .l was critical

Here is the code in case a future person see this

Code: Select all

Structure imgBackup_Structure
  i.i
EndStructure


Structure imageFile_Structure
  imgBackup.imgBackup_Structure
  List ckeys.i()
EndStructure

Structure Pixel
  Pixel.l
EndStructure



NewList imageFiles.imageFile_Structure()

AddElement(imageFiles())
; imageFiles()\imgBackup\i = CreateImage(#PB_Any, 200, 200, 32, RGBA($80, $81, $82, $FF))
; 
; If StartDrawing(ImageOutput(imageFiles()\imgBackup\i))
;   DrawingMode(#PB_2DDrawing_AllChannels)
;   Box(10, 10, 100, 100, RGBA($20, $30, $40, $FF))
;   StopDrawing()
; EndIf

AddElement(imageFiles()\ckeys())

UsePNGImageDecoder()
imageFiles()\imgBackup\i = LoadImage(#PB_Any,"unitytest2.png")

Define *Line.Pixel

If StartDrawing(ImageOutput(imageFiles()\imgBackup\i))
  
  DrawingMode(#PB_2DDrawing_AllChannels)
  
  imageFiles()\ckeys() = Point(0,0) ;RGBA($20, $30, $40, $FF)
  cKey.l = imageFiles()\ckeys()
  cBlank = RGBA(0, 0, 0, 0)
  
  If cKey <> 0
    
    *Buffer = DrawingBuffer()
    Pitch = DrawingBufferPitch()
    PixelFormat = DrawingBufferPixelFormat()
    
    
    If PixelFormat & #PB_PixelFormat_32Bits_RGB Or PixelFormat & #PB_PixelFormat_32Bits_BGR
      If PixelFormat & #PB_PixelFormat_32Bits_RGB
        Debug "RGB"
      Else
        Debug "BGR"
        cKey = RGBA(Blue(cKey), Green(cKey), Red(cKey), Alpha(cKey))
      EndIf
      Offset = 4
    Else ; 24-bit
      Offset = 3
    EndIf
    
    For y = 0 To ImageHeight(imageFiles()\imgBackup\i) - 1
      
      *Line = *Buffer + Pitch * y
      
      For x = 0 To ImageWidth(imageFiles()\imgBackup\i) - 1
        
        ;Debug Str(*Line) + " " + Str(x) + " " + Str(y) + " " + Hex(*Line\Pixel, #PB_Long) + " " + Hex(cKey, #PB_Long) + " " + Hex(cBlank, #PB_Long)
        
        If *Line\Pixel = cKey
          *Line\Pixel = cBlank
        EndIf
        
        *Line + Offset
        
      Next x
    Next y
  EndIf
  StopDrawing()
EndIf


OpenWindow(0, 0, 0, 200, 200, "Test", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(0, 0, 0, 0, 0, ImageID(imageFiles()\imgBackup\i))


Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Question about DrawingBuffers (with example)

Post by infratec »

Version with CustomFilterCallback()

Code: Select all

Structure imgBackup_Structure
  i.i
EndStructure


Structure imageFile_Structure
  imgBackup.imgBackup_Structure
  List ckeys.i()
EndStructure



Procedure.i CustomFilter(x.i, y.i, transparentColor.i, sourceColor.i)
  
  Protected.i resultColor
  
  
  If sourceColor = transparentColor
    resultColor = 0
  Else
    resultColor = sourceColor
  EndIf
  
  ;Debug Str(x) + " " + Str(y) + " " + Hex(sourceColor, #PB_Long) + " " + Hex(transparentColor, #PB_Long) + " " + Hex(resultColor, #PB_Long)
  
  ProcedureReturn resultColor
  
EndProcedure


UsePNGImageDecoder()

NewList imageFiles.imageFile_Structure()

AddElement(imageFiles())
; imageFiles()\imgBackup\i = CreateImage(#PB_Any, 200, 200, 32, RGBA($80, $81, $82, $FF))
; If StartDrawing(ImageOutput(imageFiles()\imgBackup\i))
;   DrawingMode(#PB_2DDrawing_AllChannels)
;   Box(10, 10, 50, 50, RGBA(0, 255, 0, 255))
;   StopDrawing()
; EndIf
imageFiles()\imgBackup\i = LoadImage(#PB_Any, "unitytest2.png")
If ImageDepth(imageFiles()\imgBackup\i) <> 32
  Image32 = CreateImage(#PB_Any, ImageWidth(imageFiles()\imgBackup\i), ImageHeight(imageFiles()\imgBackup\i), 32)
  If Image32
    If StartDrawing(ImageOutput(Image32))
      DrawImage(ImageID(imageFiles()\imgBackup\i), 0, 0)
      StopDrawing()
      FreeImage(imageFiles()\imgBackup\i)
      imageFiles()\imgBackup\i = Image32
    EndIf
  EndIf
EndIf


AddElement(imageFiles()\ckeys())
imageFiles()\ckeys() = RGBA(0, 255, 0, 255)

If StartDrawing(ImageOutput(imageFiles()\imgBackup\i))  
  DrawingMode(#PB_2DDrawing_CustomFilter)      
  CustomFilterCallback(@CustomFilter())
  
  Box(0, 0, ImageWidth(imageFiles()\imgBackup\i), ImageHeight(imageFiles()\imgBackup\i), imageFiles()\ckeys())
  
  StopDrawing()
EndIf


OpenWindow(0, 0, 0, 200, 200, "Test", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(0, 0, 0, 0, 0, ImageID(imageFiles()\imgBackup\i))


Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Last edited by infratec on Sat Feb 04, 2023 6:22 pm, edited 2 times in total.
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Question about DrawingBuffers (with example)

Post by Demivec »

infratec wrote: Thu Feb 02, 2023 7:36 pm Version with CustomFilterCallback()
I think your Custom filter callback is a little off. The callback should be using black instead of the source color when the source color equals the transparent color, not when the source color equals the target color. Also, the transparent color should be set independent of the callback parameters. The source color would be from the image being drawn and the target color (named transparentColor in your code) is the color already present in the output drawing.

I confess that I did not run your example yet before I posted this. Here is a version that implements the suggested changes, also untested.

Code: Select all

Structure imgBackup_Structure
  i.i
EndStructure


Structure imageFile_Structure
  imgBackup.imgBackup_Structure
  List ckeys.i()
EndStructure


Global transparentColor.i
Procedure.i CustomFilter(x.i, y.i, sourceColor.i, targetColor.i)
  
  Protected.i resultColor
  
  If sourceColor = transparentColor
    resultColor = 0 ; draw black instead of transparent color
    ;resultColor  = targetColor ; leave target color unchanged for actual transparency
  Else
    resultColor = sourceColor
  EndIf
  
  ProcedureReturn resultColor
  
EndProcedure



NewList imageFiles.imageFile_Structure()

AddElement(imageFiles())
imageFiles()\imgBackup\i = CreateImage(#PB_Any, 200, 200, 32, RGBA($80, $81, $82, $FF))

If StartDrawing(ImageOutput(imageFiles()\imgBackup\i))
  DrawingMode(#PB_2DDrawing_AllChannels)
  DrawImage(10, 10, 100, 100, RGBA($20, $30, $40, $FF))
  StopDrawing()
EndIf

AddElement(imageFiles()\ckeys())
imageFiles()\ckeys() = RGBA($20, $30, $40, $FF)


If StartDrawing(ImageOutput(imageFiles()\imgBackup\i))
  
  DrawingMode(#PB_2DDrawing_CustomFilter)      
  CustomFilterCallback(@CustomFilter())
  
  transparentColor = imageFiles()\ckeys()
  Box(0, 0, ImageWidth(imageFiles()\imgBackup\i), ImageHeight(imageFiles()\imgBackup\i))
  
  StopDrawing()
EndIf


OpenWindow(0, 0, 0, 200, 200, "Test", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(0, 0, 0, 0, 0, ImageID(imageFiles()\imgBackup\i))


Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Question about DrawingBuffers (with example)

Post by infratec »

No, it's not off :wink:

The target color in my example is the color which should be changed to transparent.
I used the color of the Box() to ensure this.

If the source color is equal to the color which should be transparent, the color value is set to 0.
The color black is meaningless, since it is fully transparent. This is done like in the original code.
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Re: Question about DrawingBuffers (with example)

Post by mestnyi »

after running your codes what should happen? :)
Post Reply