JS-конвертировать объект изображения в файл JPEG

Итак, у меня есть пользовательский ввод, который служит для загрузки фотографий. Это простой пример:

function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
        var img = new Image();
        img.onload = function(){
            console.log (img);
        }
        img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]);     
}
<input type="file" onchange="handleImage(event)"><br>

Как видите, я показываю Image () на console, Я хочу преобразовать это Image в файл JPG.

Я понял, как получить пиксели изображения, но совершенно безумно отсылать его на сервер: он слишком большой!

Я также пытался получить доступ к jpg-файлу, хранящемуся на компьютере, но ничего не достиг.

Единственный способ, который я нашел, это отправить его с form как это:

<form action="anything.php" method="post" enctype="multipart/form-data">
    <input type="file" name="fileToUpload" id="fileToUpload">
</form>   

И в PHP:

$_FILES["fileToUpload"]["tmp_name"]

Почему не с JS?

Моя конечная цель - отправить файл jpg с AJAX.

Скажите, если у вас есть вопросы.

2 ответа

Решение

Самый простой способ - использовать элемент canvas, а затем вызвать действие загрузки, позволяющее пользователю выбрать место для сохранения изображения.

Вы упоминаете, что изображение большое, но не сколько - знайте, что с канвой вы также столкнетесь с ограничениями, когда источник изображения начнет касаться области 8 КБ в размере пикселя.

Упрощенный пример (IE потребует polyfill для toBlob()).:

  • Загрузить источник изображения через вход
  • Используйте File blob напрямую как источник изображения через URL.createObjectURL()
  • При загрузке создайте временный холст, установите размер холста = размер изображения и нарисуйте изображение
  • использование toBlob() (более эффективный по памяти и производительности и не требующий перекодирования в / из Base64) для получения Blob,
  • Мы преобразуем Blob в File (объект подмножества, и он будет ссылаться на ту же память), поэтому мы также можем дать имя файла, а также (важно!) двоичный тип MIME.

Поскольку MIME-тип для последнего шага является двоичным, браузер вызовет диалог Сохранить как.

document.querySelector("input").onchange = function() {
  var img = new Image;
  img.onload = convert;
  img.src = URL.createObjectURL(this.files[0]);
};

function convert() {
  URL.revokeObjectURL(this.src);             // free up memory
  var c = document.createElement("canvas"),  // create a temp. canvas
      ctx = c.getContext("2d");
  c.width = this.width;                      // set size = image, draw
  c.height = this.height;
  ctx.drawImage(this, 0, 0);
  
  // convert to File object, NOTE: we're using binary mime-type for the final Blob/File
  c.toBlob(function(blob) {
    var file = new File([blob], "MyJPEG.jpg", {type: "application/octet-stream"});
    window.location = URL.createObjectURL(file);
  }, "image/jpeg", 0.75);  // mime=JPEG, quality=0.75
}

// NOTE: toBlob() is not supported in IE, use a polyfill for IE.
<label>Select image to convert: <input type=file></label>

Обновление: если вы просто ищете строковую (в кодировке Base-64) версию только что созданного JPEG, просто используйте toDataURL() вместо toBlob():

document.querySelector("input").onchange = function() {
  var img = new Image;
  img.onload = convert;
  img.src = URL.createObjectURL(this.files[0]);
};

function convert() {
  URL.revokeObjectURL(this.src);             // free up memory
  var c = document.createElement("canvas"),  // create a temp. canvas
      ctx = c.getContext("2d");
  c.width = this.width;                      // set size = image, draw
  c.height = this.height;
  ctx.drawImage(this, 0, 0);
  
  // convert to File object, NOTE: we're using binary mime-type for the final Blob/File
  var jpeg = c.toDataURL("image/jpeg", 0.75);  // mime=JPEG, quality=0.75
  console.log(jpeg.length)
}
<label>Select image to convert: <input type=file></label>

JavaScript на стороне клиента не может сохранять файлы. У вас есть несколько вариантов:

  1. Рендеринг изображения на <canvas> элемент. Таким образом, это может быть сохранено с правой кнопкой мыши -> сохранить изображение
  2. Вставить изображение как <img> элемент. Таким образом, это может быть сохранено с правой кнопкой мыши -> сохранить изображение
  3. Отправьте данные изображения в виде строки base64 на сервер. Сделать обработку там
  4. Используйте серверный язык, такой как PHP или Node.js, чтобы сохранить файл

Короче говоря, вы должны использовать серверную логику для сохранения файла на диске

Другие вопросы по тегам