Home > Mobile >  convert any image types to webp format using react js
convert any image types to webp format using react js

Time:01-09

I'm using react-dropzone package to add images to my app. and in my app i need to send the images to a firebase server. but before i do that i needed to handle image conversions.

so i saw this tutorial on youtube that shows how to convert images to webp format in javascript. but i can't integrate it with my react app.

can anyone please show me how to do just that?

const [files, setFiles] = useState([]);
  const [text, setText] = useState(
    "Drag and Drop or click here to upload Images"
  );
  const [drag, setDrag] = useState(false);
  const { getRootProps, getInputProps } = useDropzone({
    accept: {
      "image/*": [],
    },
    maxFiles: 9,
    onDragEnter: () => {
      setText("drag your images in here");
      setDrag(true);
    },

    onDragLeave: () => {
      setText(
        files.length == 0
          ? "Drag and Drop or click here to upload Images"
          : "Edit your Image..."
      );
      setDrag(false);
    },

    onDrop: (acceptedFiles) => {
      setText("Edit your Image...");
      setDrag(false);
      
      const newFiles = acceptedFiles.map((file) => {
        return Object.assign(file, {
          preview: URL.createObjectURL(file),
        });
      });

      if (files.length < 9) {
        setFiles((prev) => [...prev, ...newFiles]);

        files.map((file) => {
          newFiles.forEach((newFile) => {
            if (newFile.name == file.name) {
              alert(newFile.name   " is a duplicate file");

              setFiles(
                files,
                files.filter((val) => val !== newFile)
              );
            }
          });
        });
      } else if (acceptedFiles.length >= 9) {
        alert("select maximum of 9 images");
      } else {
        alert("maximum images to be selected is 9");
      }
    },
  });

if there is any packages or methods i appreciate it.

CodePudding user response:

Image conversion is something you do server side, you shouldn't try to convert the file front-end side... consider implementing a middleware between firebase and your app, even a basic express server would do

CodePudding user response:

If the images are supposed to be uploaded to a server to be shown to other users, it's probably best to leave the conversion to server-side code. The server would have to verify the validity of the file anyway.

That being said, modern browsers offer a variety of methods to work with graphics, which can be used to preform the conversion. Here's one way to do this:

/**
 * Convert between any image formats the browser supports
 * @param {Blob} source A Blob (or File) containing the image to convert
 * @param {string} type The MIME type of the target format
 * @returns {Promise<Blob>} The converted image
 */
async function convert(source, type) {
    let image = await createImageBitmap(source);

    let canvas = new OffscreenCanvas(image.width, image.height);
    let context = canvas.getContext("2d");
    context.drawImage(image, 0, 0);

    let result = await canvas.convertToBlob({ type });

    image.close();
    return result;
}

This requires a compatible browser. First of all, the browser needs to support WebP, which most browsers do. Second of all, it needs to support OffscreenCanvas, which excludes Safari (as of January 2023). In that case, you can use the following method, which does not work in WebWorkers:

/**
 * Convert between any image formats the browser supports
 * @param {Blob} source A Blob (or File) containing the image to convert
 * @param {string} type The MIME type of the target format
 * @returns {Promise<Blob>} The converted image
 */
async function convertLegacy(source, type) {
    let image = await createImageBitmap(source);

    let canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;

    let context = canvas.getContext("2d");
    context.drawImage(image, 0, 0);

    let result = await new Promise((resolve, reject) => {
        canvas.toBlob((blob) => {
            if (blob != null) {
                resolve(blob);
            } else {
                reject(new Error("Failed to convert file"));
            }
        }, type, 1);
    });

    image.close();
    return result;
}
  • Related