How would I resize a image in jQuery to a consistent aspect ratio. For example setting maximum height and have the width resize correctly. Thanks.
Here's a useful function that might do what you want:
jQuery.fn.fitToParent = function()
{
this.each(function()
{
var width = $(this).width();
var height = $(this).height();
var parentWidth = $(this).parent().width();
var parentHeight = $(this).parent().height();
if(width/parentWidth < height/parentHeight) {
newWidth = parentWidth;
newHeight = newWidth/width*height;
}
else {
newHeight = parentHeight;
newWidth = newHeight/height*width;
}
var margin_top = (parentHeight - newHeight) / 2;
var margin_left = (parentWidth - newWidth ) / 2;
$(this).css({'margin-top' :margin_top + 'px',
'margin-left':margin_left + 'px',
'height' :newHeight + 'px',
'width' :newWidth + 'px'});
});
};
Basically, it grabs an element, centers it within the parent, then stretches it to fit such that none of the parent's background is visible, while maintaining the aspect ratio.
Then again, this might not be what you want to do.
You could calculate this manually,
i.e.:
function GetWidth(newHeight,orginalWidth,originalHeight)
{
if(currentHeight == 0)return newHeight;
var aspectRatio = currentWidth / currentHeight;
return newHeight * aspectRatio;
}
Make sure you use the ORIGINAL values for the image otherwise it will degrade over time.
EDIT: example jQuery version (not tested)
jQuery.fn.resizeHeightMaintainRatio = function(newHeight){
var aspectRatio = $(this).data('aspectRatio');
if (aspectRatio == undefined) {
aspectRatio = $(this).width() / $(this).height();
$(this).data('aspectRatio', aspectRatio);
}
$(this).height(newHeight);
$(this).width(parseInt(newHeight * aspectRatio));
}
Use JQueryUI Resizeable
$("#some_image").resizable({ aspectRatio:true, maxHeight:300 });
aspectRatio: true -> maintain original aspect ratio
There's no accounting for the amount of copy and pasters out there eh! I also wanted to know this and all I saw were endless examples of scaling width OR height.. who would want the other overflowing?!
Resize width AND height without the need for a loop
Doesn't exceed the images original dimensions
Uses maths that works properly i.e width/aspect for height, and height*aspect for width so images are actually scaled properly up and down :/
Should be straight forward enough to convert to javascript or other languages
//////////////
private void ResizeImage(Image img, double maxWidth, double maxHeight)
{
double srcWidth = img.Width;
double srcHeight = img.Height;
double resizeWidth = srcWidth;
double resizeHeight = srcHeight;
double aspect = resizeWidth / resizeHeight;
if (resizeWidth > maxWidth)
{
resizeWidth = maxWidth;
resizeHeight = resizeWidth / aspect;
}
if (resizeHeight > maxHeight)
{
aspect = resizeWidth / resizeHeight;
resizeHeight = maxHeight;
resizeWidth = resizeHeight * aspect;
}
img.Width = resizeWidth;
img.Height = resizeHeight;
}
This is a good solution if you need perfect height and width aspect ratio after crop it will give perfect crop ratio
getPerfectRatio(img,widthRatio,heightRatio){
if(widthRatio < heightRatio){
var height = img.scalingHeight - (img.scalingHeight % heightRatio);
var finalHeight = height
var finalWidth = widthRatio * (height/heightRatio);
img.cropHeight = finalHeight;
img.cropWidth = finalWidth
}
if(heightRatio < widthRatio){;
var width = img.scalingWidth - (img.scalingWidth % widthRatio);
var finalWidth = width;
var finalHeight = heightRatio * (width/widthRatio);
img.cropHeight = finalHeight;
img.cropWidth = finalWidth
}
return img
}
Related
I am currently using the following javascript to resize an image to the size of it's parent, while maintaining aspect ratio and keeping the parent div square. So i have a square box with a rectangle stretched to either the max width or max height depending on orientation. This works great on first load however I cannot get the images and divs to resize on page orientation change or resize to work. Any ideas. I have tried using the window.resize and window.orientation listeners.
Original code was from:
Scale, crop, and center an image...
var aspHt = $('.aspectcorrect').outerWidth();
$('.aspectcorrect').css('height', aspHt + 'px').css('width', aspHt + 'px');
function ScaleImage(srcwidth, srcheight, targetwidth, targetheight, fLetterBox) {
var result = {
width : 0,
height : 0,
fScaleToTargetWidth : true
};
if ((srcwidth <= 0) || (srcheight <= 0) || (targetwidth <= 0) || (targetheight <= 0)) {
return result;
}
// scale to the target width
var scaleX1 = targetwidth;
var scaleY1 = (srcheight * targetwidth) / srcwidth;
// scale to the target height
var scaleX2 = (srcwidth * targetheight) / srcheight;
var scaleY2 = targetheight;
// now figure out which one we should use
var fScaleOnWidth = (scaleX2 > targetwidth);
if (fScaleOnWidth) {
fScaleOnWidth = fLetterBox;
} else {
fScaleOnWidth = !fLetterBox;
}
if (fScaleOnWidth) {
result.width = Math.floor(scaleX1);
result.height = Math.floor(scaleY1);
result.fScaleToTargetWidth = true;
} else {
result.width = Math.floor(scaleX2);
result.height = Math.floor(scaleY2);
result.fScaleToTargetWidth = false;
}
result.targetleft = Math.floor((targetwidth - result.width) / 2);
result.targettop = Math.floor((targetheight - result.height) / 2);
return result;
}
function RememberOriginalSize(img) {
if (!img.originalsize) {
img.originalsize = {
width : img.width,
height : img.height
};
}
}
function FixImage(fLetterBox, div, img) {
RememberOriginalSize(img);
var targetwidth = $(div).width();
var targetheight = $(div).height();
var srcwidth = img.originalsize.width;
var srcheight = img.originalsize.height;
var result = ScaleImage(srcwidth, srcheight, targetwidth, targetheight, fLetterBox);
img.width = result.width;
img.height = result.height;
$(img).css("left", result.targetleft);
$(img).css("top", result.targettop);
}
function FixImages(fLetterBox) {
$("div.aspectcorrect").each(function(index, div) {
var img = $(this).find("img").get(0);
FixImage(fLetterBox, this, img);
});
}
window.onload = function() {
FixImages(true);
};
Call .resize() after $(window).resize():
$(window).resize( function(){
var height = $(window).height();
var width = $(window).width();
if(width>height) {
// Landscape
$("#landscape").css('display','none');
} else {
// Portrait
$("#landscape").css('display','block');
$("#landscape").click(function(){
$(this).hide();
});
}
}).resize();
I figured out what I was missing. The first bit of javascript is setting the style of height and width. When recalling the .outerHeight it was still using the inline style to calculate the width, and hence not resizing the div. I simply used .removeAttr('style') to remove that property first and then did the resize. Working now. I simply used $(window).on("resize", resizeDiv) and wrapped my resizing into a function named resizeDiv
function resizeDiv() {
var asp = $('.aspectcorrect');
asp.removeAttr("style");
var aspHt = asp.outerWidth();
asp.css('height', aspHt + 'px').css('width', aspHt + 'px');
FixImages(true);
}
I have a fullscreen slideshow page, but the slides don't take up 100% of the background. Instead, they base size off of the browser. I want the slides to take 100% of the background. I THINK I narrowed it down to one function, but I'm not sure and not good with JavaScript yet. Here's the function:
// calculate image size, top and left position
jQuery.fn.superbgCalcSize = function(imgw, imgh) {
var options = $.extend($.fn.superbgimage.defaults, $.fn.superbgimage.options);
// get browser dimensions
var browserwidth = $(window).width();
var browserheight = $(window).height();
// use container dimensions when inlinemode is on
if (options.inlineMode === 1) {
browserwidth = $('#' + options.id).width();
browserheight = $('#' + options.id).height();
}
// calculate ratio
var ratio = imgh / imgw;
// calculate new size
var newheight = 0; var newwidth = 0;
if ((browserheight / browserwidth) > ratio) {
newheight = browserheight;
newwidth = Math.round(browserheight / ratio);
} else {
newheight = Math.round(browserwidth * ratio);
newwidth = browserwidth;
}
// calculate new left and top position
var newleft = Math.round((browserwidth - newwidth) / 2);
var newtop = Math.round((browserheight - newheight) / 2);
var rcarr = [newwidth, newheight, newleft, newtop];
return rcarr;
};
Let me know if there needs to be more code or even to link to the entire document, as I said I'm not at all experienced with JS and don't know where the problem resides.
*I've tried doing it with CSS, but I get a bug where as it's transitioning to the next image it bleeps the first image's actual size just before displaying the next and it's rather unsleek. Fixing this would also solve my question.
Recently I participated in a web project which has a huge large of images to handle and display on web page, we know that the width and height of images end users uploaded cannot be control easily and then they are hard to display. At first, I attempted to zoom in/out the images to rearch an appropriate presentation, and I made it, but my boss is still not satisfied with my solution, the following is my way:
var autoResizeImage = function(maxWidth, maxHeight, objImg) {
var img = new Image();
img.src = objImg.src;
img.onload = function() {
var hRatio;
var wRatio;
var Ratio = 1;
var w = img.width;
var h = img.height;
wRatio = maxWidth / w;
hRatio = maxHeight / h;
if (maxWidth == 0 && maxHeight == 0) {
Ratio = 1;
} else if (maxWidth == 0) {
if (hRatio < 1) {
Ratio = hRatio;
}
} else if (maxHeight == 0) {
if (wRatio < 1) {
Ratio = wRatio;
}
} else if (wRatio < 1 || hRatio < 1) {
Ratio = (wRatio <= hRatio ? wRatio : hRatio);
}
if (Ratio < 1) {
w = w * Ratio;
h = h * Ratio;
}
w = w <= 0 ? 250 : w;
h = h <= 0 ? 370 : h;
objImg.height = h;
objImg.width = w;
};
};
This way is only intended to limit the max width and height for the image so that every image in album still has different width and height which are still very urgly.
And right at this minute, I know we can create a DIV and use the image as its background image, this way is too complicated and not direct I don't want to take. So I's wondering whether there is a better way to display images with the fixed width and height without presentation distortion?
Thanks.
I would recommend taking a look at something like twitter bootstraps carousel. In this they use an image tag within a div and size it by setting the image properties to something like
img {
height: auto;
max-width: 100%;
}
You can see a small example in this little fiddle.
By setting height to auto it will keep the ratio intact.
By setting max-width: 100% it will not zoom in the image past it's original size.
I solved this problem follow the following steps:
1, Write a method to zoom in/out the image to the appropriate width and height you want:
var autoResizeImage = function(targetWidth, targetHeight, objImg) {
if (0 >= targetWidth || 0 >= targetHeight) {
// Ilegal parameters, just return.
return;
}
var img = new Image();
img.src = objImg.src;
// Calculate the width and height immediately the image is loaded.
img.onload = function() {
var hRatio;
var wRatio;
var width = img.width;
var height = img.height;
var calcWidth = width;
var calcHeight = height;
wRatio = targetWidth / width;
hRatio = targetHeight / height;
if (wRatio < hRatio) {
calcWidth = targetWidth;
calcHeight = (targetHeight / height) * targetHeight;
} else {
calcHeight = targetHeight;
calcWidth = (targetWidth / width) * targetWidth;
}
objImg.width = calcWidth;
objImg.height = calcHeight;
};
};
and then call this method in its onload event like
<img src='PATH' onload='autoResizeImage(740, 460, this)'/>
2, Create a DIV outside of this image and style the width and height that you want to image displays with:
<div style='width: 740px; height: 460px; overflow:hidden;'></div>
And then the image would display with the fixed width and height you set.
Thanks for my friends from this site.
I am opening a pop up window using window.open function
window.open('some_page.htm','','width=950,height=500');
Now what I want is when user tries to resize the window, the aspect ratio should be maintained i.e., if width is reduced then accordingly height should also get reduced and vice versa. I just want to calculate the new dimensions. So far I have tried this
function ResizeWindow()
{
var iOrignalWidth = 950;
var iOrignalHeight = 500;
var iOuterHeight = window.outerHeight;
var iOuterWidth = window.outerWidth;
var iNewOuterWidth = Math.round((iOrignalWidth / iOrignalHeight) * iOuterHeight);
var iNewOuterHeight = Math.round((iOrignalHeight / iOrignalWidth) * iNewOuterWidth);
alert("New Width: "+ iNewOuterWidth + "\t" + "New Height" + iNewOuterHeight);
}
I know that there's something wrong up there since I am not getting desired results. ANy solution on this ?
You'll want to either adjust the width to the height or visa versa, not both.
In this code, I assumed you want the width adjusted to the height:
function ResizeWindow()
{
var iOrignalWidth = 1000;
var iOrignalHeight = 500;
var iOrginalRatio = iOrignalWidth/iOrignalHeight; // 2
var iOuterWidth = window.outerWidth; // example: 1083
var iOuterHeight = window.outerHeight; //example: 600
var iNewOuterHeight = iOuterHeight; // 600
var iNewOuterWidth = Math.round(iNewOuterHeight*iOrginalRatio); //600 * 2 = 1200
alert("New Width: "+ iNewOuterWidth + "\t" + "New Height" + iNewOuterHeight);
}
I changed to original width to 1000 for the example, but you can change that back in your actual code.
You should do to accoording to one resize for maintain the aspect ratio. For example:
function ResizeWindow()
{
var iOrignalWidth = 950;
var iOrignalHeight = 500;
var iOuterHeight = window.outerHeight;
var iOuterWidth = window.outerWidth;
var w = (window.outerWidth - iOrignalWidth) / iOrignalWidth; // for exam: (1280-950) / 950= 0.34
var h = (window.outerHeight - iOrignalHeight) / iOrignalHeight; // for exam : (800 - 500) / 500= 0.60
var newWidth;
var newHeight;
if (w<h)
{
// If percentage of width is less than percentage of height, Resize should be according to percentage of width.
newWidth = iOrignalWidth * w * 100;
newHeight = iOrignalHeight * w *100;
}
else
{
// If percentage of height is less than percentage of width, Resize should be according to percentage of height.
newWidth = iOrignalWidth * h * 100;
newHeight = iOrignalHeight * h *100;
}
alert("New Width: "+ newWidth + "\t" + "New Height" + newHeight );
}
So that maintain the aspect ratio is always preserved.
So, I'm using facebox to display images neatly, and I wrote a function to help with handeling the size of really big images: (fiddle: http://jsfiddle.net/LPF85/)
function open_img_in_face_box(id, width){
max_width = $j(document).width();
max_height = $j(document).height();
padding = 50;
max_width = max_width - (2 * padding);
max_height = max_height - (2 * padding);
passed_width = width || max_width;
var img = $j('#' + id);
dom_img = document.getElementById(id);
// display
jQuery.facebox({ image: img.attr('src') });
// center and adjust size
var aspect_ratio = img.width() / img.height();
var img_width = passed_width;
var img_height = passed_width / aspect_ratio;
window_center_y = max_height / 2;
window_center_x = max_width / 2;
offset_y = window_center_y - (img_height / 2);
offset_x = window_center_x - (img_width / 2);
var fbx = $j('#facebox');
fbx.css('left', offset_x + 'px !important');
fbx.css('top', offset_y + 'px !important')
$j("#facebox .image img").load(function(){
$j(this).width(img_width);
});
}
but the problem is that the image remains full size, and never gets changed to 500 (the current value I'm using for img_width).
How do I change the width of the image after it loads, but quickly enough so no one notices?
I've tested this in Chrome, and Safari with this html:
<img id="facebox_img" onclick="open_img_in_face_box('facebox_img', 500)" src="/medias/50/original.jpg" width="300" />
Here you go:
Replace:
$j("#facebox .image img").load(function(){
$j(this).width(img_width);
});
with:
$j(document).bind('reveal.facebox', function() {
$j("#facebox .image img").width(width);
})
This new code listens to the reveal event and sets the width accordingly once all the elements are in place.
Try this
$j("#facebox .image img").each(function(){
$(this).load(function(){
$j(this).width(img_width);
}).attr("src", $j(this).attr("src"));
});