Trying to Pass Todataurl with Over 524288 Bytes Using Input Type Text

Trying to Pass ToDataURL with over 524288 bytes Using Input Type Text

Try sending canvas as Blob at javascript; use fopen() with php://input as parameter to read Blob, stream_copy_to_stream or file_get_contents() , file_put_contents() to process file at php

See HTMLCanvasElement.toBlob()

if (!HTMLCanvasElement.prototype.toBlob) {
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
value: function (callback, type, quality) {

var binStr = atob( this.toDataURL(type, quality).split(',')[1] ),
len = binStr.length,
arr = new Uint8Array(len);

for (var i=0; i<len; i++ ) {
arr[i] = binStr.charCodeAt(i);
}

callback( new Blob( [arr], {type: type || 'image/png'} ) );
}
});
}

Beyond $_POST, $_GET and $_FILE: Working with Blob in JavaScript and PHP

<?php

// choose a filename
$filename = "hello.json";

// the Blob will be in the input stream, so we use php://input
$input = fopen('php://input', 'rb');
$file = fopen($filename, 'wb');

// Note: we don't need open and stream to stream, we could've used file_get_contents and file_put_contents
stream_copy_to_stream($input, $file);
fclose($input);
fclose($file);

?>

How to replace a file input's content by the result of canvas.toDataURL?

It seems we cannot modify the <input type="file">, but we can add the data to another text field (as advised by @PatrickEvans) or an <input type="hidden">:

function doit() {    var file = document.getElementById('file').files[0],        canvas = document.getElementById('canvas'),        hidden = document.getElementById('hidden'),        ctx = canvas.getContext("2d"),        img = document.createElement("img"),        reader = new FileReader();          reader.onload = function(e) {         img.src = e.target.result;    }        img.onload = function () {         ctx.drawImage(img, 0, 0);        hidden.value = canvas.toDataURL("image/jpeg", 0.5);    }    reader.readAsDataURL(file);}
<input type="file" onchange="doit();" id="file" />
<form action="/upload" method="post"><input type="hidden" id="hidden" /><input type="submit" /></form>
<canvas id="canvas" style="display: none" />

How I put the canvas content as a file in a input type file

The best is still to send files through a FormData and AJAX.

But since it seems it's for personal use, and that you already have something working with a <form>, you can probably use what is still an hack exposed in this answer of mine. Beware this still works only in latest Chromium and Geckos browsers (no Webkit support, which means no iOS support).

So the step by step is,

  • draw on your canvas.
  • export it to a Blob using the HTMLCanvasElement.toBlob() method.
  • build a File from this Blob
  • build a DataTransfer object
  • append the File to the DataTransfer's items list
  • set the .files property of your <input type="file"> to the DataTransfer's .files

// draw on the canvas
const canvas = document.createElement( "canvas" );
const ctx = canvas.getContext( "2d" );
ctx.fillStyle = "red";
ctx.fillRect( 20, 20, 260, 110 );

// convert to Blob (async)
canvas.toBlob( (blob) => {
const file = new File( [ blob ], "mycanvas.png" );
const dT = new DataTransfer();
dT.items.add( file );
document.querySelector( "input" ).files = dT.files;
} );

// to prove the image is there
document.querySelector( "#test" ).onclick = (evt) => {
const file = document.querySelector( "input" ).files[ 0 ];
document.body.appendChild( new Image() )
.src = URL.createObjectURL( file );
};
<form method="POST">
<input type="file" name="file"><br>
<button>submit</button> (check your dev tools network panel to see the File is sent)
</form>
<br>
<button id="test">
load input's content as image
</button>

Sending canvas.toDataURL() as FormData

To send binary data in a POST request, you want to use a Blob. A Blob represents raw binary data. To get a Blob of a Canvas, you can use the toBlob method.

Once you have the Blob instance, you can add the Blob to the FormData using the append method. The append method accepts Blob instances as the second argument. You can even pass an optional third argument to append to specify the filename to send with the Blob to the server.

The blob will be received on the server as file data.

An example of this in action:

const canvas = document.getElementById('my-canvas');
canvas.toBlob(function(blob) {
const formData = new FormData();
formData.append('my-file', blob, 'filename.png');

// Post via axios or other transport method
axios.post('/api/upload', formData);
});


Related Topics



Leave a reply



Submit