1

So I'm Making a meme generator and the user has the option to enter an image link OR upload a local file from storage.

Here is my html for link/local storage upload.

  <div class="Main_Grid_Item Link_Upload_Div">
    <form action="/" method="POST">
      <p>Enter Image Link:</p>
      <input class="Image_Input" type="text" name="Link_Url" placeholder="Image Link"><br>
      <button class="Image_Submit" type="submit" name="button">Submit Image</button>
    </form>
  </div>

  <div class="Main_Grid_Item File_Upload_Div">
    <form>
      <p>Upload Image:</p>
      <input id = "UploadOutput" class = "Upload_Output" type="text" placeholder="Image Name After Upload" readonly><br>
      <label for="ImgStorage" class="Image_Upload_Label">Upload Image</label>
      <input type='file' id="ImgStorage" />
    </form>
    <br>
  </div>

And for specifically file uploading this is my javascript which was mostly copied from this stack thread: Javascript image upload and display

function readURL(input) {
//if picture exists then create a new FileReader
if (input.files && input.files[0]) {
var reader = new FileReader();

//the image with specified id gets url
reader.onload = function (e) {
  $("#blah").attr("src", e.target.result);
};

//reads picture
reader.readAsDataURL(input.files[0]);

} }

Just to clarify that entering a link/uploading an images DOES WORK both ways and the image is shown properly on screen. The problem that I'm facing is when taking a "screenshot" with html 2 canvas.

This is my javascript code for taking a screenshot with html2canvas

//takes screenshot of Meme with overlay
$("#Save_Meme_Button").on("click", memeScreenShot);

function memeScreenShot() {
   html2canvas(document.querySelector(".Main_Image_Div")).then((canvas) => {
    document.body.appendChild(canvas);
   });
}

This code essentially takes a "screenshot" of the image and then shows it below the website. The problem is that when I upload an image with a url, "screenshotting" the image will sometimes produce a blank image.

However if I go to the image-url, download the image on local storage, and then use the other option to upload an image from local storage, the image is saved sucessfully instead of showing a blank image.

Is there any reason why a blank screenshot of the image sometimes happens when uploaded by link compared to being uploaded by local storage? I looked a bit on the docs about something about a tainted canvas but I'm not sure if thats the problem because I get no errors in the console when uploading/saving an image : https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image#:~:text=Security%20and%20tainted%20canvases,-Because%20the%20pixels&text=As%20soon%20as%20you%20draw,an%20exception%20to%20be%20thrown.

I am getting a cors error when the image is uploaded blank when I enable the option to useCors. I think this is why the link option is not working and the local storage is working enter image description here

Code that displays image

<div id = "MainImageDiv" class="Main_Image_Div">
  <% if(typeof imgUrl !== 'undefined'){ %>
  <img id="blah" src=<%= imgUrl %> class="Main_Image" /></img>
  <% } else{ %>
  <img id="blah" src="/images/stonks.png" class="Main_Image" /></img>
  <% } %>
  <p id="TopTextPar" class="Top_Text"></p>
  <p id="BottomTextPar" class="Bottom_Text"></p>
</div>
  • Can you include the code that draws the image to the canvas? I am thinking that you need to wait for it to load. – luek baja Aug 03 '20 at 04:04
  • The only code relating to the canvas is the one i provided. When the div is screenshotted, the screenshotted image is just added to the bottom of this website. Like this : https://codepen.io/MySecondLife/pen/QQjLgN And I dont think i need to wait for the image to render because it works properly when I upload an image with local storage and sometimes works (which is the problem) when i upload an image with a url – SiciliaDraco Aug 03 '20 at 04:08
  • Have you included the code that displays the image from the URL? – luek baja Aug 03 '20 at 23:46
  • I've added it. I enabled the useCors option in html2canvas and it gives me a CORS error. I've tried using this proxy https://www.npmjs.com/package/html2canvas-proxy but i'm not sure where to enable the proxy in my app.js(Node). I will attach my repo at the end of my post also – SiciliaDraco Aug 04 '20 at 00:07

1 Answers1

0

Ok so I managed to solve my problem. It's essentially a copy of the solution on this thread : html <img src=...> works but JS Image loading cause CORS error.

What I essentially did was take the image url the user entered and rendered it onto a seperate canvas.

And I enabled cors with this https://cors-anywhere.herokuapp.com/. I got a (cors enabled?) data url out of this and then all I had to do is append an image with the image src as the data url I received.

Here's my solved code :

// Changes image based on link
$("#ImageSubmit").click(function(){
//makes the previous meme dissapear and gets the url of the inputted link
$("#blah").css("display","none");
const imgUrl = $("#ImageInput").val();

function loadImgAsBase64(url, callback) {
//creates camvas amd image element + allows cors + loads image
   let canvas = document.createElement('CANVAS');
   let img = document.createElement('img');
   img.setAttribute('crossorigin', 'anonymous');
   img.src = 'https://cors-anywhere.herokuapp.com/' + url;

img.onload = () => {
    canvas.height = img.height;
    canvas.width = img.width;
    let context = canvas.getContext('2d');
    context.drawImage(img, 0, 0);
    let dataURL = canvas.toDataURL('image/png');
    canvas = null;
    callback(dataURL);
  };
}

loadImgAsBase64(imgUrl, (dataURL) => {
    $("#MainImageDiv").append(`<img id="blah" class = "Main_Image Link_Meme" 
    src="${dataURL}">`);
});

loadImgAsBase64(imgUrl)

});