help with cropped with and height

105 views
Skip to first unread message

Michael Caruana

unread,
Jun 29, 2015, 7:15:19 PM6/29/15
to jquery-g...@googlegroups.com
Hi there,

I'm a big fan of this lightweight image resizing tool, very impressed with what it does so simply and uncomplicated. I've happily been using it to apply transformations to my images, but when it's time to crop I get stuck. The plugin always returns the same width and height, no matter what the scale used. I'm using a canvas object, so first I centre the canvas, then rotate, then try to apply cropping, but I have no idea how to find the width and height of the viewport to crop the original image.

Could somebody please explain to me how it works, maybe an example. Here's my code so far:

var data = picture[0].getData();
var canvas = document.createElement("canvas");
canvas.width=400, canvas.height=400;
var context = canvas.getContext("2d");
context.translate(200, 200);
context.scale(data.scale, data.scale)
context.rotate(data.rotate * Math.PI / 180);

So far so good... now how to crop?

context.drawImage(picture[0],data.x,data.y,???,???,-200,-200,400,400);

Cheers,
Michael.

mgag....@gmail.com

unread,
Jun 30, 2015, 5:27:04 PM6/30/15
to jquery-g...@googlegroups.com, mike...@gmail.com
Hi Michael, thanks for using the forum to post your concern.

You set the dimensions of the viewport (or window, or guillotine) when you initialize Guillotine, like this:

picture.guillotine({width: 400, height: 300})

Here width and height stand for the dimensions you want for the viewport or size of the area to crop, not the image. In the documentation, the 3rd step of the setup outlines this.

So, when you call:

data = picture.guillotine('getData')

And get:

{ scale: 1.4, angle: 270, x: 10, y: 20, w: 400, h: 300 }

w
and h are the dimensions you specified for the viewport, and being so they never change.

To get the dimensions of the scaled image, you need to use the original dimensions and the scale attribute:

newImgWidth  = originalImgWidth  * data.scale
newImgHeight
= originalImgHeight * data.scale

The reason for data being like that is to match the data used by server-side libraries to handle images, like ImageMagick or GraphicsMagick. Maybe that's why it's not so intuitive for you using the canvas.

I'm a bit short of time for now but I hope this can help you get going. If you have more questions just ask and I'll try to answer in a couple of days.

Hapy coding!




Michael Caruana

unread,
Jul 2, 2015, 12:17:54 PM7/2/15
to jquery-g...@googlegroups.com, mike...@gmail.com
Hi there,

Thankyou for taking the time to respond, it's greatly appreciated.
Yes I am aware that the image is scaled, so multiplying the width and height by the scale is the perfectly simple and logical way to determine the scaled width and height. I apologise for not being clearer with my question. My question was, how do I get the cropped width and height? Anyway I eventually figured out the canvas statement uses the original width & height for the input and the scaled width & height for the output and the excess lengths are discarded, which means I don't need to know the actual cropping width & height values (it just fills the canvas and trims the excess.)

Anyway on to my last problem, I don't know how to position rotated images that are rescaled. The example below works except for the question marks when the image is rotated to 90 degrees, where is the new Y-axis starting point?

var px = -canvas.width / 2; var py = -canvas.height / 2;
ctx.translate(-px,-py);
ctx.rotate(data.angle * Math.PI/180);
if( data.angle == 0 ) { 
  ctx.drawImage(source[0], data.x/data.scale,data.y/data.scale,source[0].width,source[0].height, px,py,source[0].width*data.scale,source[0].height*data.scale); // works fine
} else if( data.angle == 90 ) { 
  ctx.drawImage(source[0], data.y/data.scale,(source[0].width-data.x)/data.scale,source[0].height,-source[0].width, py,???,source[0].height*data.scale,source[0].width*data.scale);
}

Cheers,
Michael.

Michael Caruana

unread,
Jul 6, 2015, 11:21:48 PM7/6/15
to jquery-g...@googlegroups.com
Well I finally figured this out, here it is for anyone else who gets stuck like I did.
The key was to use the original dimensions, not those reported by the guillotine object.

var picture = $('#sample_picture'); //guillotine object
var data = picture.guillotine('getData');
var canvas = document.createElement('canvas');
canvas.width=data.w;canvas.height=data.h;
var ctx = ctx = canvas.getContext("2d");
var cx = -canvas.width / 2; var cy = -canvas.height / 2;
ctx.translate(-cx,-cy); //move to centre of canvas
ctx.rotate(data.angle * Math.PI/180);
ctx.scale(data.scale, data.scale);
var source = $('#original_picture'); //same src as guillotine object
if( data.angle == 0 ) { // simple offsets from canvas centre & scale
ctx.drawImage(source[0],(cx-data.x)/data.scale, (cy-data.y)/data.scale );
} else if( data.angle == 90 ) { // swap axis and reverse the new y origin
ctx.drawImage(source[0],(cy-data.y)/data.scale, (-1*source[0].height)+((-cx+data.x)/data.scale) );
} else if( data.angle == 180 ) { // reverse both origins
ctx.drawImage(source[0],(-1*source[0].width)+((-cx+data.x)/data.scale), (-1*source[0].height)+((-cy+data.y)/data.scale) );
} else if( data.angle == 270 ) { // swap axis and reverse the new x origin
ctx.drawImage(source[0],(-1*source[0].width)+((-cy+data.y)/data.scale), (cx-data.x)/data.scale );
}
var dataURL = canvas.toDataURL();

My nightmare is over.
Cheers

mgag....@gmail.com

unread,
Jul 7, 2015, 2:10:54 PM7/7/15
to jquery-g...@googlegroups.com, mike...@gmail.com
Hi Michael, so glad that you could figure it out and thanks for sharing it for future readers.

I've been meaning to put some time aside to go through the code you posted but it's been a bussy week.

It doesn't make it up but might help, a couple of extensive resources about HTML canvas:

- HTML canvas deep dive
Canvassing

Bests.

Pablo Rocha

unread,
Dec 24, 2015, 7:10:25 AM12/24/15
to jQuery Guillotine
Michael Caruana,

Really nice job! thank you for share.

If this was post in the GitHub as an example would save the time of many others.

Anyway, thank you again.

Martin gan

unread,
Jan 20, 2016, 11:30:41 PM1/20/16
to jQuery Guillotine
@Michael Caruana when the data.angle equal to 90 and then it doesn't crop at correct position and the final output is not as same as in the preview. Any idea how to solve this issue?

Martin gan

unread,
Jan 20, 2016, 11:35:48 PM1/20/16
to jQuery Guillotine
Hi Michael, 

when data angle is 90 or 270 and then it doesn't crop at correct x/y position, thus the final output is not as same as in the preview. Any idea how to solve this issue?

On Tuesday, July 7, 2015 at 11:21:48 AM UTC+8, Michael Caruana wrote:
Reply all
Reply to author
Forward
0 new messages