Help converting short p5.js program to Purebasic
Posted: Mon Jul 08, 2024 10:51 pm
I have went as far as my knowledge of p5.js will allow me to in trying to implement this code:
From this page: https://spencerszabados.github.io/blog/ ... dithering/
This is what I have got so far:
Any tips on how to make the last step to add dithering to the output image?
Code: Select all
let c = null; //number of grey levels
let d = null; //dimension of threshold map
let M = null; //threshold map
let img = null; //image reference
let img_Y = null; //bitmap array of relative luminance values of img
let img_D = null; //final dithered image
function preload() {
//initilize constants
c = 4;
d = 8;
//define threshold map
M = [[0,32,8,40,2,34,10,42],
[48,16,56,24,50,18,58,26],
[12,44,4,36,14,46,6,38],
[60,28,52,20,62,30,54,22],
[3,35,11,43,1,33,9,41],
[51,19,59,27,49,17,57,25],
[15,47,7,39,13,45,5,37],
[63,31,55,23,61,29,53,21]];
for(let i=0; i<d; i++){
for(let j=0; j<d; j++){
M[i][j] = M[i][j]/(d*d);
}
}
//load image and allocate space for luminance image
img = loadImage("assests/mike.jpg");
img_Y = new Array(img.width*img.height);
}
function setup() {
//no loop canvas
noLoop();
pixelDensity(1);
createCanvas(img.width,img.height);
}
function draw(){
img_D = createImage(img.width,img.height);
img_D.loadPixels();
img.loadPixels();
for(let i=0; i<img.height; i++){
for(let j=0; j<img.width; j++){
let idx = 4*(i*img.width+j);
let T = M[j%d][i%d];
img_D.pixels[idx ] = 255*Math.floor(T+img.pixels[idx]*(c-1)/255)/(c-1);
img_D.pixels[idx+1] = 255*Math.floor(T+img.pixels[idx+1]*(c-1)/255)/(c-1);
img_D.pixels[idx+2] = 255*Math.floor(T+img.pixels[idx+2]*(c-1)/255)/(c-1);
img_D.pixels[idx+3] = 255;
}
}
img_D.updatePixels();
image(img_D,0,0);
}
This is what I have got so far:
Code: Select all
Global c=4
Global d=8
DataSection
Data.a 0,32,8,40,2,34,10,42, ; Set up bayer 8x8 array.
48,16,56,24,50,18,58,26,
12,44,4,36,14,46,6,38,
60,28,52,20,62,30,54,22,
3,35,11,43,1,33,9,41,
51,19,59,27,49,17,57,25,
15,47,7,39,13,45,5,37,
63,31,55,23,61,29,53,21
EndDataSection
Dim M.f(8,8)
For y=1 To d
For x=1 To d
Read.a temp
M(x,y)=temp/(8*8)
Next
Next
#height=1000
#width=1500
UsePNGImageDecoder()
OpenWindow(0,0,0,#width,#height,"Ordered Dithering Test")
LoadImage(2,"image.png") ; Load an image to image 2 for processing - This is the source image
ImageGadget(0,0,0,ImageWidth(2),ImageHeight(2),ImageID(2)) ; Set up a gadget to display it.
SetGadgetState(0,ImageID(2))
Dim img_Y(ImageWidth(2),ImageHeight(2)) ; I'm not sure where this is used in the code to be honest.
Dim imgnew(ImageWidth(2),ImageHeight(2)) ; My plan is to use this array to draw the New dithered image to,
; so that I can have the source image As the live Drawing image used With StartDrawing()
; to Read from And just write To the Array instead of drawing To a second image.
CreateImage(3,ImageWidth(2),ImageHeight(2)) ; Create new image to draw dithered image to from imgnew() array after source image has been processed.
StartDrawing(ImageOutput(2)) ; Read from Image(2)
For i=0 To ImageHeight(2)-1
For j=1 To ImageWidth(2)-1
idx = 4*(i*ImageWidth(2)+j) ; I think I will have to use a different idx method in Purebasic
T = M(j%d,i%d)
imgnew(j,i)=Point(j,i) ; For now I just copy image(2) to array imgnew()
; to be honest at this stage i'm not sure how idx is used in p5.js
Next
Next
StopDrawing()
StartDrawing(ImageOutput(3))
For y=0 To ImageHeight(2)-1
For x=0 To ImageWidth(2)-1
Plot(x,y,imgnew(x,y))
Next
Next
StopDrawing()
ImageGadget(1,750,0,ImageWidth(3),ImageHeight(3),ImageID(3)) ; Set up a gadget to display image(3)
SetGadgetState(1,ImageID(3))
Repeat
Event = WaitWindowEvent()
Select Event
EndSelect
Until Event = #PB_Event_CloseWindow Or quit=#True
Any tips on how to make the last step to add dithering to the output image?