Преобразуя холст в BLOB через Кроппер в JS

Я создал приложение, используя Кроппер.js для обрезки изображений. Приложение работает, и изображение обрезается, после этого я пытаюсь отправить обрезанное изображение в виде blob на сторону сервера для хранения,

на Кроппер.js документация мы можем использовать холст.toDataURL чтобы получить URL-адрес данных, или использовать холст.toBlob чтобы получить blob и загрузить его на сервер с FormData. когда я пытался холст.toDataURL() Я получаю строку base64, но на самом деле мне нужно отправить файл как blob, поэтому я попытался с холст.toBlob(), но я получаю Uncaught TypeError: canvas.toBlob is not a function в chrome и TypeError: Not enough arguments to HTMLCanvasElement.toBlob. в Firefox

может кто-нибудь пожалуйста, скажите мне какое-то решение для этого

мой код такой

var canvas = $image.cropper("getCroppedCanvas", undefined);
var formData = new FormData();
formData.append('mainImage', $("#inputImage")[0].files[0]);
formData.append('croppedImage', canvas.toBlob());

2 ответов


метод toBlob является асинхронным и требует двух аргументов, функции обратного вызова и типа изображения (есть необязательный третий параметр для качества):

пустоту холста.toBlob (обратный вызов, тип, encoderOptions);

пример

if (typeof canvas.toBlob !== "undefined") {
  canvas.toBlob(function(blob) {
      // send the blob to server etc.
      ...
  }, "image/jpeg", 0.75);
}
else if (typeof canvas.msToBlob !== "undefined") {
  var blob = canvas.msToBlob()
  // send blob
}
else {
  // manually convert Data-URI to Blob (if no polyfill)
}

не все браузеры поддерживают его (IE нуждается в префиксе, msToBlob, и он работает иначе, чем стандартный), а Chrome нуждается в polyfill.

обновление (для редактирования OP, теперь удалено) основная причина, почему обрезанное изображение больше, потому что оригинал JPEG, новый PNG. Вы можете изменить это с помощью toDataURL:

var uri = canvas.toDataURL("image/jpeg", 0.7);  // last=quality

перед передачей его в ручную data-uri в Blob. Я бы рекомендовал использовать polyfill, как если бы браузер поддерживал toBlob (), это будет во много раз быстрее и использовать меньше накладных расходов памяти, чем происходит путем кодирования данных-uri.


правильное использование:https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob

вы должны передать обратный вызов и использовать объект blob внутри обратного вызова. toBlob() не возвращает blob, а принимает обратный вызов, который предоставляет blob в качестве параметра.

var canvas = document.getElementById("canvas");

canvas.toBlob(function(blob) {
  var newImg = document.createElement("img"),
      url = URL.createObjectURL(blob);

  newImg.onload = function() {
    // no longer need to read the blob so it's revoked
    URL.revokeObjectURL(url);
  };

  newImg.src = url;
  document.body.appendChild(newImg);
});