20

I have an image URL "https://cdn.shopify.com/s/files/1/0234/8017/2591/products/young-man-in-bright-fashion_925x_f7029e2b-80f0-4a40-a87b-834b9a283c39.jpg", and want to convert it into javaScript File Type object.

: File
   lastModified: 1591250106736
   lastModifiedDate: Thu Jun 04 2020 11:25:06 GMT+0530 (India Standard 
   Time) {}
   name: "7.jpeg"
   size: 369742
   type: "image/jpeg"
   webkitRelativePath: ""
4
  • I'm sorry, but I don't get it. You have a path to an image. Ok. What do you want to do with that path? Or with the image. "Convert it to File Type" makes no sense for me. Commented Jun 3, 2020 at 18:10
  • 1
    @Torf I think the OP wants to get the file as a browser File object Commented Jun 3, 2020 at 18:11
  • @Torf, i want to convert image source into browser File object Commented Jun 4, 2020 at 6:35
  • 1
    Maybe that has been answered here: stackoverflow.com/questions/43358456/… Commented Jun 4, 2020 at 6:45

5 Answers 5

26

Convert your image src https://cdn.shopify.com/s/files/1/0234/8017/2591/products/young-man-in-bright-fashion_925x_f7029e2b-80f0-4a40-a87b-834b9a283c39.jpg into Base64 ULR format and than convert Base64 URL into javaScript File Object.

***Here is the code for converting "image source" (url) to "Base64".***

let url = 'https://cdn.shopify.com/s/files/1/0234/8017/2591/products/young-man-in-bright-fashion_925x_f7029e2b-80f0-4a40-a87b-834b9a283c39.jpg'
const toDataURL = url => fetch(url)
      .then(response => response.blob())
      .then(blob => new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onloadend = () => resolve(reader.result)
      reader.onerror = reject
      reader.readAsDataURL(blob)
     }))


***Here is code for converting "Base64" to javascript "File Object".***

  function dataURLtoFile(dataurl, filename) {
     var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
     bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
     while(n--){
     u8arr[n] = bstr.charCodeAt(n);
     }
   return new File([u8arr], filename, {type:mime});
  }


*** Calling both function ***

  toDataURL(url)
  .then(dataUrl => {
     console.log('Here is Base64 Url', dataUrl)
     var fileData = dataURLtoFile(dataUrl, "imageName.jpg");
     console.log("Here is JavaScript File Object",fileData)
     fileArr.push(fileData)
   })
Sign up to request clarification or add additional context in comments.

Comments

16

I'm assuming you want to run this in a browser environment. You can use the native fetch() method, read the response as Blob and convert it to a File object.

contentType should be based on the type of the actual image downloaded.

You can read more about several approaches and browser support to convert a Blob to File here:

Convert blob to file

How to convert Blob to File in JavaScript

const url = 'https://cdn.shopify.com/s/files/1/0234/8017/2591/products/young-man-in-bright-fashion_925x_f7029e2b-80f0-4a40-a87b-834b9a283c39.jpg?v=1572867553'
const fileName = 'myFile.jpg'

fetch(url)
  .then(async response => {
    const contentType = response.headers.get('content-type')
    const blob = await response.blob()
    const file = new File([blob], fileName, { contentType })
    // access file here
  })

3 Comments

any pointers on how to also attach a temporary path for the File object?
@thammada.ts When I used this, I got text/html for the file type, and the link was an image.. any idea how to solve this? thanks
@user10033434 the content type is sent by the target server. It's possible that the link you are fetching returns an incorrect type in the header. If you are sure about the content type you can used a fixed value like for example contentType: 'image/jpeg' or contentType: 'image/png'
11

For more elegant solution use this

const getUrlExtension = (url) => {
    return url
      .split(/[#?]/)[0]
      .split(".")
      .pop()
      .trim();
  }

const onImageEdit = async (imgUrl) => {
    var imgExt = getUrlExtension(imgUrl);

    const response = await fetch(imgUrl);
    const blob = await response.blob();
    const file = new File([blob], "profileImage." + imgExt, {
      type: blob.type,
    });
}

1 Comment

I received "Failed to fetch" when I gave it an URL of an image on AWS S3. Why is that? the image can be seen on the browser.
1

Answer from @Alphapico works like a charm, just have to return the file:

const onImageEdit = async (imgUrl) => {
    var imgExt = getUrlExtension(imgUrl);

    const response = await fetch(imgUrl);
    const blob = await response.blob();
    const file = new File([blob], "profileImage." + imgExt, {
      type: blob.type,
    });
    
    return file;

}

might be case to case scenario

Comments

0

I would use a function like this one instead of trying to guess the filename and type:

function getExtensionFromMimeType(mimeType) {
  const mimeToExtension = {
      'image/jpeg': 'jpg',
      'image/png': 'png',
      'image/gif': 'gif',
      'image/bmp': 'bmp',
      'image/svg+xml': 'svg',
      'image/webp': 'webp',
      // Add more MIME types and their extensions as needed
  };

  return mimeToExtension[mimeType] || '';
}


const urlToFile = async (url) => {
    const response = await fetch(url);
    const blob = await response.blob();

    // Get the filename from Content-Disposition
    const contentDisposition = response.headers.get('Content-Disposition');
    let fileName = contentDisposition?.match(/filename="([^"]+)/)?.[1];

    if (!fileName) {
        fileName = "image." + getExtensionFromMimeType(blob.type);
    }
    
    const file = new File([blob], fileName, { type: blob.type });

    return file;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.