This one uses canvas.ToDataURL(...)
function getBase64Image(img) {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);
  const dataURL = canvas.toDataURL("image/png");
  return dataURL;
}
This one works in more cases because it avoids canvas by re-fetching the img.src
const getBase64FromUrl = async (url) => {
  const data = await fetch(url);
  const blob = await data.blob();
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.readAsDataURL(blob); 
    reader.onloadend = () => {
      const base64data = reader.result;   
      resolve(base64data);
    }
  });
}
As a bonus, this one uses both functions before to read all images in the page and uses the first function if it works, otherwise it uses the second one, and returns a markdown image embedding of the image with its alt text as the title and the base64 as the source.
const images = document.getElementsByTagName('img');
[...images].forEach(async img => {
  let base64;
  try {
    base64 = getBase64Image(img);      
  } catch (error) {
    base64 = await getBase64FromUrl(img.src);
  };
  const markdown = ``;
  console.log(markdown, img);
})