Page 1 of 2
Question about DrawingBuffers (with example)
Posted: Thu Feb 02, 2023 3:35 pm
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!
Re: Noob question about imageBuffer function
Posted: Thu Feb 02, 2023 5:26 pm
by infratec
I'm missing a functional example.
Re: Noob question about imageBuffer function
Posted: Thu Feb 02, 2023 5:39 pm
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
Re: Question about DrawingBuffers (with example)
Posted: Thu Feb 02, 2023 5:59 pm
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
Re: Question about DrawingBuffers (with example)
Posted: Thu Feb 02, 2023 6:06 pm
by Josepho
Im afraid that doesnt have any effect Mijikai
Re: Question about DrawingBuffers (with example)
Posted: Thu Feb 02, 2023 6:14 pm
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.
Re: Question about DrawingBuffers (with example)
Posted: Thu Feb 02, 2023 6:17 pm
by Josepho
This is the image, the target is to remove the green background

Re: Question about DrawingBuffers (with example)
Posted: Thu Feb 02, 2023 6:18 pm
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
Re: Question about DrawingBuffers (with example)
Posted: Thu Feb 02, 2023 6:22 pm
by infratec
And for speed reasons you can also check:
Re: Question about DrawingBuffers (with example)
Posted: Thu Feb 02, 2023 6:22 pm
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
Re: Question about DrawingBuffers (with example)
Posted: Thu Feb 02, 2023 6:32 pm
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
Re: Question about DrawingBuffers (with example)
Posted: Thu Feb 02, 2023 7:36 pm
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
Re: Question about DrawingBuffers (with example)
Posted: Sat Feb 04, 2023 11:14 am
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
Re: Question about DrawingBuffers (with example)
Posted: Sat Feb 04, 2023 2:46 pm
by infratec
No, it's not off
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.
Re: Question about DrawingBuffers (with example)
Posted: Sat Feb 04, 2023 2:53 pm
by mestnyi
after running your codes what should happen?
