Reputation: 243
This answer https://stackoverflow.com/a/17862644 is a good example of using steps to downscale an image. My simple question is: how can I automatically determine how many steps to use to downscale an image.
Upvotes: 3
Views: 137
Reputation: 4068
Based on codetaku's answer and Ken's answer in another post (Html5 canvas drawImage: how to apply antialiasing) I was able to create a little helper function that would automatically create the steps after determining how many steps to have.
Here's the fiddle: http://jsfiddle.net/44svz/2/
function step(img, num, w, h, nw, nh){
if ( nw/w >= 1 && nh/h >= 1 ) return img;
var oc = document.createElement('canvas'),
octx = oc.getContext('2d'),
can = document.createElement('canvas'),
ctx = can.getContext('2d'),
mult = 1;
num = Math.max(0, num-1);
oc.width = w * 0.5;
oc.height = h * 0.5;
octx.drawImage(img, 0, 0, oc.width, oc.height);
if ( num ) {
for ( var i = 1; i<num; i++ ) {
octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);
mult = mult * 0.5;
}
}
can.width=nw;
can.height=nh;
ctx.drawImage(oc, 0, 0, oc.width * mult, oc.height * mult, 0, 0, nw, nh);
return can;
}
This function needs to know the original dimensions and target dimensions nw
, nh
. The equation for determining how many steps to take is below:
var det = Math.ceil(Math.log(original_width/new_width) / Math.log(2));
I think original width and new width can also be replaced by the products of the dimensions as noted by Ken. I don't know how much more accurate that'll be however.
Hope that helps!
Upvotes: 3
Reputation: 508
Exactly as Russell said in the first comment, but in order to justify this being an answer, I will elaborate a bit.
You can code this up to work iteratively until the image is the final desired size; you reduce by half each time until the final size is greater than or equal to half of the current image.
This results in a number of iterations equivalent to taking the log, base 2, of the full size divided by the target size. So if you wanted to explicitly specify the number of steps, your equation would be
ceiling(log(fullSize/targetSize) / log(2))
However, it makes more sense to simply make a while loop; while the target size is less than half of the current size, cut the current size in half. Once the while loop is done, scale down to the target size directly.
Upvotes: 2