Upload pGraphics to server

I’d like to save a pGraphics object as a PNG-image to the server.
I found a way to upload the canvas object.
Is it possible to export a pGraphics object in a similar way?

function saveImage() {
    // Export canvas
    // These rows are addressing the canvas.
    // Instead i want to grab the data of a pGraphics object called 'output'
    let defaultCanvas = document.getElementById("defaultCanvas0");
    let dataURL = defaultCanvas.toDataURL("image/png");
    // let dataURL = output.toDataURL("image/png") -> doesn't work. 

    document.getElementById('hidden_data').value = dataURL;
    var formData = new FormData(document.forms["uploadForm"]);

    // Upload request
    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'photo_upload.php', true);

    xhr.upload.onprogress = function (e) {
        if (e.lengthComputable) {
            var percentComplete = (e.loaded / e.total) * 100;
            console.log(percentComplete + '% uploaded');
            alert('Succesfully uploaded');
        }
    };

    xhr.onload = function () {

    };
    xhr.send(formData);
};

This is how the image is saved to the server.

<?php
    $upload_dir = "images/";
    $img = $_POST['hidden_data'];
    $img = str_replace('data:image/png;base64,', '', $img);
    $img = str_replace(' ', '+', $img);
    $data = base64_decode($img);
    $file = $upload_dir . mktime() . ".png";
    $success = file_put_contents($file, $data);
    print $success ? $file : 'Unable to save the file.';
?>

Hi, your example is doing a post request to a server. You can do that in Processing with this library: https://github.com/runemadsen/HTTP-Requests-for-Processing

It has a method called .addFile(). They don’t show an example for uploading a file, but it looks easy to do.

Hi hamoid.

Thanks the mentioned library is for processing. My project works with p5js.
Meanwhile I found a workaround.

When exporting I call the draw function once, but scale everything up first and leave out controls and visual aids, save the file and the return to the default state and draw everything normal again.
This seems to work quite fine.

The scaling function lets you use most of the code just as it is. Only be aware when you use the width or the height somewhere, because they actually change.


let scaleOutput = 1;
let hoverDrawing = true;

// Setup and stuff
// ...

function exportImage() {
    setResolution(5, false);  // -> Scales everything up 5 times. 
    saveImage()               // -> Calls a function on how to save the image
    setResolution(1, true);   // -> Back to normal size. 
}

function setResolution(s, h = true) {
	scaleOutput = s;
	hoverDrawing = h;
	resizeCanvas(scaleOutput * 1000, scaleOutput * 640);
	output = createGraphics(scaleOutput * 1000, scaleOutput * 640);
	draw();
}

function draw() {

	// ...
	// Clear Canvas
	background(255);
	output.clear();
	hover.clear();

	// Draw Output
	output.push();
	output.scale(scaleOutput);
	// ... draw visuals
	output.pop();

	// Draw output image
	image(output, 0, 0);
	if (checkClickBorder() && hoverDrawing) image(hover, 0, 0)
}

Ah good that you found out a solution.

You mentioned pGraphics instead of p5.Graphics and that got me confused. Processing (Java) has a type called PGraphics while p5.js uses p5.Graphics :slight_smile:

1 Like