Преобразовать холст HTML5 в файл, который будет загружен?

Стандартная загрузка файла HTML работает следующим образом:

<g:form method="post" accept-charset="utf-8" enctype="multipart/form-data"  
     name="form" url="someurl">

    <input type="file" name="file" id="file" />

</form>

В моем случае я загрузил изображение в холст html5 и хочу отправить его как файл на сервер. Я могу сделать:

var canvas; // some canvas with an image
var url = canvas.toDataURL();

Это дает мне изображение /png как base64.

Как отправить образ base64 на сервер так же, как это делается с файлом типа ввода?

Проблема заключается в том, что файл base64 не имеет тот же тип, что и файл, который находится внутри input type="file".

Можно ли преобразовать base64, чтобы типы были одинаковыми для сервера?

Ответ 1

Из соображений безопасности вы не можете напрямую установить значение элемента ввода файла.

Если вы хотите использовать элемент ввода файла:

  • Создайте изображение с холста (как вы это сделали).
  • Отобразить это изображение на новой странице.
  • Попросите пользователя щелкнуть правой кнопкой мыши-сохранить на своем локальном диске.
  • Затем они могут использовать ваш элемент ввода файла для загрузки этого вновь созданного файла.

В качестве альтернативы вы можете использовать Ajax для POST для данных холста:

Вы спросили о blob:

var blobBin = atob(dataURL.split(',')[1]);
var array = [];
for(var i = 0; i < blobBin.length; i++) {
    array.push(blobBin.charCodeAt(i));
}
var file=new Blob([new Uint8Array(array)], {type: 'image/png'});


var formdata = new FormData();
formdata.append("myNewFileName", file);
$.ajax({
   url: "uploadFile.php",
   type: "POST",
   data: formdata,
   processData: false,
   contentType: false,
}).done(function(respond){
  alert(respond);
});

Примечание: blob обычно поддерживается в последних браузерах.

Ответ 2

Изображение холста необходимо преобразовать в base64, а затем из base64 в двоичный. Это делается с помощью .toDataURL() и dataURItoBlob()

Это был довольно сложный процесс, который требовал собрать несколько ответов SO, различные сообщения в блогах и учебные пособия.

Я создал учебное пособие, которое вы можете проследить, пройдя через процесс.

Ответ 3

Другое решение: отправить данные в var url в скрытом поле, декодировать и сохранить его на сервере.

Пример в Python Django:

if form.is_valid():
    url = form.cleaned_data['url']
    url_decoded = b64decode(url.encode())        
    content = ContentFile(url_decoded) 
    your_model.model_field.save('image.png', content)