resize image by area
I am trying to write a javascript function to resize an image based on a given area (or in my case (somewhat inaccurate) 'average dimension' since that's easier to think in terms of. Rather than feeding in maximum height and width, I want to feed in maximum area so that long or narrow images will appear visually to be roughly the same size.
I'm getting really caught on the math aspect of it, though... just how to logic it, as I haven't done much math of late.
Basically, given an aspect ratio I want to determine the maximum size within an area.
Something like this:
function resizeImgByArea(img, avgDimension){
var w = $(img).width();
var h = $(img).height();
var ratio = w/h;
var area = avgDimension * avgDimension;
var targetHeight //something involving ratio and area
var targetWidth //something involving ratio and area
$(img).width(t开发者_如何学运维argetWidth);
$(img).height(targetHeight);
}
Not sure if this is on topic here, but I'm not able to brain it.
Sounds like you want to constrain the thumbnail's pixels to be as close as possible to the average area as all the other thumbnails, right?
So basically, given the h/w of the original image, and a target area A:
h * w = original image's pixel size (let's got with 640x480 = 307,200 pixels)
A = maximum number of pixels allowed (let's go for 100x100 = 10,000 pixels)
307,200 / 10,000 = 30x reduction
original aspect ratio = 640 / 480 = 1.3333 : 1
To calculate the new thumbnail's x/y size:
newX * newY = 10000
newX = newY * 1.333
(newY * 1.333) * newY = 10000
newY^2 * 1.333 = 10000
newY^2 = 10000 / 1.333
newY^2 = 7502
newY = 86.6 -> 87
newX = 87 * 1.333 = 115.97 -> 116
116 x 87 = 10,092 pixels
if we'd rounded down on the thumbnail sizes, we'd get 86x114 = 9,804 pixels
so... to convert your 640x480 image to a standard 10,000-ish pixel size, you need a new image size of 86-87 height and 114-116 width.
Are you looking for something like:
function resizeImgByArea(img, avgDimension) {
var w = $(img).width();
var h = $(img).height();
var maxWidth = avgDimension;
var maxHeight = avgDimension;
var divisor;
var targetWidth = w;
var targetHeight = h;
if (w > maxWidth || h > maxHeight) {
// Set the divisor to whatever will make the new image fit the dimensions given
if((w - maxWidth) > (h - maxHeight)) {
divisor = w / maxWidth;
}
else {
divisor = h / maxHeight;
}
targetWidth = w / divisor;
targetHeight = h / divisor;
}
$(img).width(targetWidth);
$(img).height(targetHeight);
}
It isn't that hard.
maxPix = average^2
maxPix = x * h + x * w
average^2 = x*h + x*w //: x
average^2/x = h+w
inverse and multiply with average^2
x = average^2 / (h+w)
then multiply h and w with x to get the new dimensions
Here is the function I came up with that's simpler than some mentioned and does what I need. It constrains to a set maxWidth, but not height because of the particular requirements I was using.. it would probly be appropriate to throw on a maxHeight as well as well as some cleanup, but it gets 'er done.
function resizeImgByArea(imgId, avgDimension){
var node, w, h, oldArea, oldAvgDimension, multiplicator, targetHeight, targetWidth, defAvgDimension;
node = $('#' + imgId);
node.css('width', '').css('height', '');
var maxW = $('#' + imgId).css('maxWidth');
if (maxW){
defAvgDimension = maxW;
} else {
defAvgDimension = 200;
}
avgDimension = (typeof avgDimension == "undefined")?'defAvgDimension':avgDimension;
w = node.width();
h = node.height();
oldArea = w*h;
oldAvgDimension = Math.sqrt(oldArea);
if (oldAvgDimension > avgDimension){
multiplicator = avgDimension / oldAvgDimension;
targetHeight = h * multiplicator;
targetWidth = w * multiplicator;
node.width(targetWidth);
node.height(targetHeight);
}
}
function fitImageInArea(img, area) {
var r;
if (img.width/img.height >= area.width/area.height) {
r = area.width / img.width;
img.width = area.width;
img.height = img.height*r;
} else {
r = area.height / img.height;
img.height = area.height;
img.width = img.width*r;
}
return img;
}
Give an image or anything with width
and height
properties as an argument. area
argument assume width
and height
properties too.
精彩评论