joplin-notes/Export-9fad9947-5bd5-4195-952b-6512c5a4beb1/Web development 83dd4e6675f04ba782a6865a434a0598/React 5b9af27e2c194a4cb22a32306e53c39f/Extract data uri from image 5610c5f6df1b49978b3a19/Full codebase for conversion to data uri ea49e40ac.md
2026-11-04 00:33:23 +05:30

3.7 KiB

Full codebase for conversion to data uri

JSX:

const App = () => {
  const [src, setSrc] = useState("");
  const [uri, setUri] = useState("");

  const createImage = () => {
    return new Promise((resolve, reject) => {
      const image = new Image();
      image.crossOrigin = "anonymous";
      image.src = src;

      image.onload = () => {
        resolve(image);
      };

      image.onerror = (e) => {
        reject(e);
      };
    });
  };

  useEffect(async () => {
    // const image = new Image();
    // image.crossOrigin = "anonymous";
    // image.src = src;

    // image.onload = () => {
    const image = await createImage();
    const canvas = document.createElement("canvas");
    canvas.width = image.width;

    canvas.height = image.height;

    const ctx = canvas.getContext("2d");
    ctx.drawImage(image, 0, 0);
    const dataURL = canvas.toDataURL("image/png");
    setUri(dataURL);
    // console.log(dataURL);
    // };
  }, [src]);

  const handleChange = (e) => {
    setSrc(e.target.value);
  };

  const copyToClipboard = () => {
    navigator.clipboard.writeText(uri).then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
  };

  const uploadImage = () => {
    const fileElement = document.createElement("input");
    fileElement.setAttribute("type", "file");
    fileElement.setAttribute("accept", "image/*");
    fileElement.click();

    fileElement.onchange = (e) => {
      const reader = new FileReader();
      reader.readAsDataURL(fileElement.files[0]);

      reader.onload = () => {
        setSrc(reader.result);
      };
    };
  };

  return (
    <div>
      <div className="mainSection">
        <div className="inputs">
          <input
            type="text"
            placeholder="Insert the url of image"
            onChange={handleChange}
          />
          <div className="or">OR</div>
          <div className="uploadImageSection">
            <button className="uploadImage" onClick={uploadImage}>
              Upload Image
            </button>
          </div>
        </div>
        <br />

        <div className="base64Section">
          <div className="base64URI">{uri.substr(0, 100)}</div>
          <button
            onClick={copyToClipboard}
            title="Copy data URI"
            className="copyToClipboard"
          >
            <i class="fa fa-copy"></i>
          </button>
        </div>

        {src ? <img src={src} alt="image" /> : ""}
      </div>
    </div>
  );
};

CSS:

.mainSection {
  margin: auto;
  margin-top: 3rem;
  width: fit-content;
}

.mainSection input[type="text"] {
  height: 1.5rem;
  width: 200px;
}

.mainSection .inputs {
  width: fit-content;
  margin: auto;
}

.mainSection .or {
  text-align: center;
  margin-top: 1rem;
}

.mainSection .uploadImageSection {
  margin-top: 1rem;
  width: 100%;
  display: flex;
  justify-content: center;
}

.mainSection .uploadImage {
  cursor: pointer;
  padding: 0.5rem;
  font-size: 1.3rem;
}

.mainSection .base64Section {
  margin: 1rem auto;
  padding: 0.5rem;
  display: flex;
  width: fit-content;
  align-items: center;
  justify-content: center;
}

.base64Section button {
  cursor: pointer;
  background-color: white;
  border: none;
  border: 1px solid black;
  height: fit-content;
  padding: 0.5rem;
  font-size: 1.2rem;
  transition: all 0.1s ease-in-out;
}

.base64Section button:hover {
  background-color: rgb(100, 100, 100, 0.3);
}

.mainSection .base64URI {
  height: 3rem;
  border: 1px solid black;
  width: 200px;
  border-radius: 3px;
  overflow: hidden;
  /* max-width: 400px; */
  margin-right: 1rem;
}

.mainSection img {
  margin-top: 1rem;
  max-height: 200px;
}