Set file-input file from url
Asked Answered
H

1

7

I have a file input:

<input type="file" id="myImageInput" accept="image/*">

I have a preview img:

<img src="http://myImageUrl" id="myImagePreview">

I want to set the image as a file for the file-input#myImageInput.

What I try:

  1. Create Base64 from the img#myImagePreview:
function toDataUrl(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
        var reader = new FileReader();
        reader.onloadend = function() {
            callback(reader.result);
        }
        reader.readAsDataURL(xhr.response);
    };
    xhr.open('GET', url);
    xhr.responseType = 'blob';
    xhr.send();
}

let base64Image;
toDataUrl("http://myImageUrl",function(x){
    base64Image = x;
})
  1. Create DataTransfer and add the base64Image to it:
const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
new DataTransfer(); // specs compliant (as of March 2018 only Chrome)
dT.items.add(new File(['myNewFile'], base64Image ));
document.querySelector('#myImageInput').files = dT.files;
  1. Console.log the #myImageInput.files:
0: File
lastModified: 1593986842957
lastModifiedDate: Mon Jul 06 2020 00:07:22 GMT+0200 (Central European Summer Time) {}
name: "data:image/jpeg;base64,/9j/4AAQSkZJRgABCSAQAASABIAAADD"
size: 9
type: ""
webkitRelativePath: ""

This doesn't look right but it actually set a "file"...

  1. Now I try to preview the new image from the myImageInput:
function previewFile() {
  var preview = document.querySelector('#myImagePreview');
  var file    = document.querySelector('#myImageInput').files[0];
  var reader  = new FileReader();

  reader.onloadend = function () {
    preview.src = reader.result;
    console.log(reader.result);
  }

  if (file) {
    reader.readAsDataURL(file);
  } else {
    preview.src = "";
  }
}

previewFile();

But the image is broken. #myImagePreview:

<img src="data:application/octet-stream;base64,bXlOZyXdGacWxl" id="myImagePreview">

Do I need to feed the DataTransfer.items a blob? a base64 or a fileObject to make this work?

Helper answered 5/7, 2020 at 22:2 Comment(2)
@charlietfl that is not true anymore. https://mcmap.net/q/81138/-how-to-set-file-input-value-when-dropping-file-on-page-duplicateHelper
Ok my bad....was that way for many years, didn't know it was viable nowPreconception
G
3

Your File constructor is incorrect, the file data is the first parameter and the filename the second.
Also you are putting base64 data into the file instead binary data.
Below the bob is used to create the File instead of a base64 string.

function toDataUrl(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
        callback(xhr.response);
    };
    xhr.open('GET', url);
    xhr.responseType = 'blob';
    xhr.send();
}

let image;
toDataUrl("http://myImageUrl",function(x){
    image = x;
})

...

const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
new DataTransfer(); // specs compliant (as of March 2018 only Chrome)
dT.items.add(new File([image], 'myNewFile'));
document.querySelector('#myImageInput').files = dT.files;
Geode answered 6/7, 2020 at 19:11 Comment(1)
perfect! so a File Object is needed and it is created from a blob like this:datatransfer.items.add(new File([x:blob],name:string)); thxHelper

© 2022 - 2024 — McMap. All rights reserved.