4

How can I crop an area of an image using JavaScript? As I have read, I must use a canvas to project the image on it.

With the following code I am cutting an area of an image, but the size of the cut area is not the indicated one.

  var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
      var imageObj = new Image();

      imageObj.onload = function() {
        // draw cropped image
        var sourceX = 0;
        var sourceY = 0;
        var sourceWidth = 500;
        var sourceHeight = 150;
        var destWidth = sourceWidth;
        var destHeight = sourceHeight;
        var destX = canvas.width / 2 - destWidth / 2;
        var destY = canvas.height / 2 - destHeight / 2;

        context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
     

      };
      imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
    <canvas id="myCanvas" style="border:1px solid red"></canvas>

I am trying to represent in this image what I want to do.

enter image description here

my main problem is that the canvas does not adapt to the size of the cropped image and the final height (sourceHeight ) and width (sourceWidth ) They are not the ones I specified

How can i fix it?

isherwood
  • 58,414
  • 16
  • 114
  • 157
yavg
  • 2,761
  • 7
  • 45
  • 115

2 Answers2

1

The problem

Your source "width" is the same width as the image.

The solution

When using ctx.drawImage with 9 arguments, think of it like a cut and paste.

You want to "cut" the outline in red, and "paste" it to your new - centered - location. You want to "cut" all the way up to the half way point of the source. So you need to select all the way up to the half way point of the image.

I also suggest maybe changing the variable name from "source" to "crop" (cropX, cropWidth, etc) to better reflect its purpose, as it is not really the width of the "source" anymore.

If you want the image to fill the entire canvas, "paste" it with the canvas' width and height at (0,0)

context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, canvas.width, canvas.height);

The code

...
var context = canvas.getContext('2d');
    var imageObj = new Image();

    imageObj.onload = function() {
        // crop from 0,0, to 250,150
        var cropX = 0;
        var cropY = 0;
        var cropWidth = 250;
        var cropHeight = 150;

        //resize our canvas to match the size of the cropped area
        canvas.style.width = cropWidth;
        canvas.style.height = cropHeight;

        //fill canvas with cropped image
        context.drawImage(imageObj, cropX, cropY, cropWidth, cropHeight, 0, 0, canvas.width, canvas.height);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
...
Octal
  • 187
  • 10
  • what I intend is simply that the gray occupies 100% of the cropped image. `width 500px` and` height 150px` – yavg Dec 10 '20 at 15:25
  • You want the cropped image to fill the canvas? – Octal Dec 10 '20 at 15:28
  • the canvas has a space to the sides, based on your answer I want the canvas to be the size of the cropped image – yavg Dec 10 '20 at 15:33
  • Hmm I am very confused by what you need. Could you not resize the canvas? Or is that what you need help with? – Octal Dec 10 '20 at 15:34
  • So you are making a quiz on something? Thats pretty neat! But that screenshot looked like it was your code verifying a users answer. I'm not sure how that is supposed to help me understand what you need when rendering your image... – Octal Dec 10 '20 at 15:45
  • Ah I think I understand, in the image you have in your question - on the right - you have a small piece of the cropped result. You want that image to be the entire canvas? – Octal Dec 10 '20 at 15:47
  • yes! I want that. cut the pieces of the canvas where the image is not contained – yavg Dec 10 '20 at 15:55
  • thanks friend! currently your code give me an error "Uncaught TypeError: Cannot read property 'drawImage' of undefined" an ultimate question,is posible convert the cropped image to base64? – yavg Dec 10 '20 at 16:15
  • Regarding the first point. Make sure you are selecting your context properly. That means context is undefined, there is probably a typo in the ID of the canvas, or in the construction of the context object. And for your second point: [try this](https://stackoverflow.com/questions/6150289/how-can-i-convert-an-image-into-base64-string-using-javascript) – Octal Dec 10 '20 at 16:17
  • I hope not to bother you, but I have put your code here and it follows if it works, I also tried putting the code to get the image in base64 https://jsfiddle.net/edkq9175/ – yavg Dec 10 '20 at 16:30
  • No problem. I apologize for the delayed reply. First off, it doesn't work because you replaced all of your code with my code. I meant for you to take the relavent code and replace your's with it. I have edited it to hopefully make it that more obvious. Regarding base64 this has gone a bit off topic for this question, but it does appear to work, when you use my code properly. https://jsfiddle.net/OctalDeveloper/rx84ebsn/ – Octal Dec 10 '20 at 17:38
0

You'll need to tell the canvas the size of the image you're trying to display to ensure the canvas has the desiredWith size;

However, the size of your example image is 438 × 300, which makes it hard to crop to 500px.

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.src = 'https://placehold.it/700x700';
imageObj.onload = function() {

    const desiredWidth = 500;
    const desiredHeight = 150;
    
    canvas.width = desiredWidth;
    canvas.height = desiredHeight;

    context.drawImage(imageObj, 0, 0, desiredWidth, desiredHeight, 0, 0, desiredWidth, desiredHeight);
    
    console.log(canvas.width, canvas.height);
};
<canvas id="myCanvas" style="border:1px solid red"></canvas>
0stone0
  • 34,288
  • 4
  • 39
  • 64