0

I know there are tons of posts about image resizing and I read a lot of them. I was able to resize an image uploaded by a user. But I genuinely don't understand how to post the form with this new and resized image.

I implemented the resizing method from this post, but I don't understand the part where the blob is appended to the formData.

const input = this.$refs.input;
const file = input.files[0];

// Load the image
var reader = new FileReader();
reader.onload = function (readerEvent) {
  var image = new Image();
  image.onload = function (imageEvent) {
    // Resize the image
    var canvas = document.createElement('canvas');
    const width = 200;
    const height = 300;
    canvas.width = width;
    canvas.height = height;
    canvas.getContext('2d').drawImage(image, 0, 0, width, height);
    var dataUrl = canvas.toDataURL('image/jpeg');
    var resizedImage = dataURLToBlob(dataUrl);

    // I don't understand that part
    // $.event.trigger({
    //   type: 'imageResized',
    //   blob: resizedImage,
    //   url: dataUrl,
    // });

    // I understand that an image input value can not be changed programatically
    // const url = URL.createObjectURL(resizedImage);
    // input.value = url;
  };
  image.src = readerEvent.target.result;
};
reader.readAsDataURL(file);

To be clear, this is a Rails project and the form (that includes many other fields than just the image) is built with simple_form.

Should I actually place the file input out of the form? Should I intercept the form submit call to manually construct the formData, including the resized image? Should I maybe do the resizing on the server side?

My understanding is probably wrong, so I would greatly appreciate any help!

Loïc Boset
  • 343
  • 3
  • 13

1 Answers1

0

you probably want to do the image resizing on the server any way cuz the browser dose a bad job at compressing it. ( see how to compress a base64 image to custom size )


fyi, it's possible to update a FileList programatically in a round about way... Is it possible to update FileList?


About the part of where you want to append the file to a formdata you have to use canvas.toBlob to get it as a file instead of a base64 string.

async function showDemo (blob) {
  const file = blob // simulated getting a file from input

  // Load the image
  const bitmap = await createImageBitmap(blob)
  
  // Resize the image
  var canvas = document.createElement('canvas')
  const width = 200
  const height = 300
  canvas.width = width;
  canvas.height = height;
  canvas.getContext('2d').drawImage(bitmap, 0, 0, width, height);
  canvas.toBlob(function (resizedImage) {
    const fd = new FormData()
    const img = new Image()
    fd.append('upload', file, 'image.jpg')
    img.src = URL.createObjectURL(resizedImage)
    document.body.append(img)
    // upload
    // fetch(url, { method: 'post', body: fd })
  }, 'image/jpeg', 1);
}

// just to get a dummy image:
fetch('https://dummyimage.com/600x400/000/fff').then(res =>res.blob()).then(showDemo)
Endless
  • 34,080
  • 13
  • 108
  • 131