w3c / FileAPI

File API
https://w3c.github.io/FileAPI/
Other
104 stars 44 forks source link

add dataURL method #136

Closed petele closed 4 years ago

petele commented 5 years ago

The new .text(), .stream() and .arrayBuffer() methods are great. It would be nice to have a dataURL() method as well.

mkruisselbrink commented 5 years ago

Could you elaborate a bit on the use cases for that method? So far my ideas for adding the extra methods was to make Blob as similar to a Body as makes sense. But Body doesn't have a dataURL() method, so adding that would be adding functionality that doesn't exist for Body.

dtruffaut commented 5 years ago

One use case could be reading image blobs. And asynchronize the existing method reader.readAsDataURL(blob).

Snippet / Example :

// Top level code
// Read an url image and convert it to webp in the browser
// (for information, currently, this code runs in a worker)

const result = await fetch(url);
const blob = await result.blob();
const bmp = await createImageBitmap(blob);
const canvas = new self.OffscreenCanvas(width, height);
const o = {
  alpha: false,
  desynchronized: true,
  preserveDrawingBuffer: true
}
const ctx = canvas.getContext('2d', o);
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
ctx.drawImage(bmp, 0, 0, width, height);
const blob = await canvas.convertToBlob({ type: 'image/webp', quality: 0.8 });

const dataUrl = await blobToDataUrl(blob); // <-- To replace with "await blob.dataURL()"

console.log(`dataUrl`, dataUrl.toString().substring(0, 50));
// Then, message dataUrl to main thread and upload it to Firebase Storage.
// ...etc.

// ---------------------------------------------

// Would be nice to replace this function 
// with a "await blob.dataURL()"
// 
// Convert a blob to a dataUrl

const blobToDataUrl = async (blob) => {
  // Promise function
  const f = (resolve, reject) => {
    // Create new FileReader
    const reader = new FileReader();
    // Define error listener
    reader.addEventListener('error', () => {
      reject(false);
    }, { passive: true });
    // Define success listener
    reader.addEventListener('load', () => {
      if (!reader.result) {
        reject();
        return;
      }
      resolve(reader.result);
    }, { passive: true });
    // Read
    reader.readAsDataURL(blob);  // <----- AHA .readAsDataURL
  };
  return new Promise(f);
}
annevk commented 5 years ago

That doesn't really illustrate the use case to me. For uploading you could upload the blob as well.

annevk commented 4 years ago

Closing per above. If a popular library does this we could reconsider.