Hassan Baig
Hassan Baig

Reputation: 15814

TypeError when using drawImage method of CanvasRenderingContext2D (pure Javascript)

I'm getting an image file from an input element, which I then catch in a vanilla javascript snippet via e.target.files[0]. Next, I'm attempting to standardize the dimensions of this image (in case it exceeds the benchmarks) via passing e.target.files[0] to source_img in the function below:

function process_img(source_img,new_width, new_height, mime_type, quality){
    var canvas = document.createElement('canvas');
    canvas.width = new_width;
    canvas.height = new_height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(source_img, 0, 0, new_width, new_height);
    return dataURItoBlob(canvas.toDataURL(mime_type,quality/100),mime_type);
}

function dataURItoBlob(dataURI,mime_type) {
  var byteString = atob(dataURI.split(',')[1]);
  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); }
  return new Blob([ab], { type: mime_type });
}

This is currently giving me the following error:

TypeError: Argument 1 of CanvasRenderingContext2D.drawImage could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement, ImageBitmap.

My question is two-fold:

1) Why am I getting the error and what's the most efficient way to solve it?

2) What's the most efficient way to accomplish this image resizing/processing? E.g. ways to circumvent the base64 string (while ensuring cross-browser compatibility)? Essentially I want to know how the industry pros do it for scalable projects.

I'd prefer answers with illustrative examples (along with explanations).

Note: Professional server-side dev here who's a JS newbie. Let's stick to pure JS for the scope of this question. JQuery's on my radar, but I won't touch it till I learn JS fundamentals.

Upvotes: 0

Views: 728

Answers (1)

xianshenglu
xianshenglu

Reputation: 5309

question 1:change your process_img function to this:

 function process_img(source_img, new_width, new_height, mime_type, quality) {
     var canvas = document.createElement('canvas');
     canvas.width = new_width;
     canvas.height = new_height;
     var ctx = canvas.getContext("2d");

     var reader = new FileReader();
     var img = document.createElement('img');

     reader.onload = function() {
         img.src = this.result;
         document.body.appendChild(img); //maybe
         img.style.display = 'none'; //maybe
         img.onload = function() {//better
             ctx.drawImage(img, 0, 0, new_width, new_height);
             return dataURItoBlob(canvas.toDataURL(mime_type, quality / 100), mime_type);
         };
     };

     reader.readAsDataURL(source_img);
 }

the principle is transform your imageFile to HTMLimgElement with src by FileReader;

Upvotes: 1

Related Questions