Page 1 of 1

Is There a Workaround to DrawingBuffer() Command?

Posted: Tue Aug 12, 2025 3:57 am
by cameo
Hi Everyone,
The command DrawingBuffer() is not implemented in SpiderBasic. While I am new to SpiderBasic, I have used PureBasic for many years and I have come to rely on DrawingBuffer() for direct access to the pixels in an image or screen. I know that there is the Point(x,y) command but I need fast access to all the pixels for applications such as image processing (eg. filters). Is there any way, say using Javascript commands, to access the pixel data pointer to a SpiderBasic Image?
Many Thanks

Hi Fred,
Do you have plans to expose the DrawingBuffer() pointer in an upcoming SB update? If so, how soon?
Many Thanks

Re: Is There a Workaround to DrawingBuffer() Command?

Posted: Thu Aug 14, 2025 10:58 am
by Dirk Geppert
Maybe this will help you?

Code: Select all

; Demo: Pixel-Buffer einer SpiderBasic-Image via Inline-JS anfassen

;EnableExplicit

Enumeration
  #Img
  #Win
  #Canvas
EndEnumeration

; 1) Arbeitsbild erzeugen und befüllen
CreateImage(#Img, 320, 240, 24)

If StartDrawing(ImageOutput(#Img))
  Box(0, 0, OutputWidth(), OutputHeight(), RGB(40, 60, 100))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  For i = 0 To 200
    Circle(Random(OutputWidth()-1), Random(OutputHeight()-1), 6, RGBA(Random(255), Random(255), Random(255), 200))
  Next
  StopDrawing()
EndIf

; 2) Optional anzeigen (Fenster + Canvas)
OpenWindow(#Win, 0, 0, 340, 260, "SpiderBasic Pixel-Access", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(#Canvas, 10, 10, 320, 240)

If StartDrawing(CanvasOutput(#Canvas))
  DrawImage(ImageID(#Img), 0, 0)
  StopDrawing()
EndIf

; 3) Das zugrunde liegende Canvas der Image holen
Define imgCanvas = ImageID(#Img)  ; <- liefert im Web das <canvas>-Element

; 4) Inline JS: RGBA-Buffer greifen, bearbeiten, zurückschreiben
;    (Hier zwei Filter als Beispiel: invert und grayscale)
EnableJS
(() => {
  const canvas = v_imgcanvas;                               // ImageID(#Img) -> <canvas>
  const ctx     = canvas.getContext('2d', { willReadFrequently: true });
  const w = canvas.width, h = canvas.height;

  // kompletten Pixelpuffer holen
  const imgData = ctx.getImageData(0, 0, w, h);
  const data = imgData.data;                                // Uint8ClampedArray [R,G,B,A,...]

  // --- Beispiel 1: invert (sehr schnell) ---
  for (let i = 0; i < data.length; i += 4) {
    data[i  ] = 255 - data[i  ];  // R
    data[i+1] = 255 - data[i+1];  // G
    data[i+2] = 255 - data[i+2];  // B
    // A unverändert
  }

  // --- Beispiel 2: optional: einfache Graustufe ---
  // for (let i = 0; i < data.length; i += 4) {
  //   const y = (data[i] + data[i+1] + data[i+2]) / 3 | 0;
  //   data[i] = data[i+1] = data[i+2] = y;
  // }

  // zurück ins Canvas schieben
  ctx.putImageData(imgData, 0, 0);
})();
DisableJS

; 5) Anzeige aktualisieren
If StartDrawing(CanvasOutput(#Canvas))
  DrawImage(ImageID(#Img), 0, 0)
  StopDrawing()
EndIf


Re: Is There a Workaround to DrawingBuffer() Command?

Posted: Fri Aug 15, 2025 3:20 am
by cameo
Hi Dirk,
Thank you for your code, it is very helpful. I was in fact exploring similar code approaches but seeing it all put together is very useful. With regard to execution speed, I made some quick comparisons and the inline JS approach is amazingly fast. Now that I know this approach is fast enough, I can delve further into the details of using Javascript for graphics processing. Thank you again.
regards,
John