44

I'd like to start a discussion about the image resizing using jQuery.

That's my contribution: But I think I'm far away from the solution. What about the cropping? Who can help me?

$(document).ready(function() {
    $('.story-small img').each(function() {
    var maxWidth = 100; // Max width for the image
    var maxHeight = 100;    // Max height for the image
    var ratio = 0;  // Used for aspect ratio
    var width = $(this).width();    // Current image width
    var height = $(this).height();  // Current image height

    // Check if the current width is larger than the max
    if(width > maxWidth){
        ratio = maxWidth / width;   // get ratio for scaling image
        $(this).css("width", maxWidth); // Set new width
        $(this).css("height", height * ratio);  // Scale height based on ratio
        height = height * ratio;    // Reset height to match scaled image
    }

    // Check if current height is larger than max
    if(height > maxHeight){
        ratio = maxHeight / height; // get ratio for scaling image
        $(this).css("height", maxHeight);   // Set new height
        $(this).css("width", width * ratio);    // Scale width based on ratio
        width = width * ratio;    // Reset width to match scaled image
    }
});

});

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
michele
  • 449
  • 1
  • 4
  • 3
  • Do you have any idea why this won't work with `var maxWidth = $(document).width();`. Have a look: http://jsfiddle.net/KHdZG/16/ – Mike Feb 08 '12 at 15:24
  • 2
    Since jQuery/javascript runs in the client, if a file on the server is 2 MB, the browser still has to download the full 2 MB before rendering a 100x100 image. Correct? –  Jan 05 '14 at 23:20

14 Answers14

27

You need to recalculate width and height after first condition. Here is the code of entire script:

$(document).ready(function() {
    $('.story-small img').each(function() {
    var maxWidth = 100; // Max width for the image
    var maxHeight = 100;    // Max height for the image
    var ratio = 0;  // Used for aspect ratio
    var width = $(this).width();    // Current image width
    var height = $(this).height();  // Current image height

    // Check if the current width is larger than the max
    if(width > maxWidth){
        ratio = maxWidth / width;   // get ratio for scaling image
        $(this).css("width", maxWidth); // Set new width
        $(this).css("height", height * ratio);  // Scale height based on ratio
        height = height * ratio;    // Reset height to match scaled image
    }

    var width = $(this).width();    // Current image width
    var height = $(this).height();  // Current image height

    // Check if current height is larger than max
    if(height > maxHeight){
        ratio = maxHeight / height; // get ratio for scaling image
        $(this).css("height", maxHeight);   // Set new height
        $(this).css("width", width * ratio);    // Scale width based on ratio
        width = width * ratio;    // Reset width to match scaled image
    }
});
Aleksandar Janković
  • 821
  • 1
  • 10
  • 18
  • 2
    You forgot to close the outer function with }); – DarkNeuron Dec 13 '15 at 15:45
  • Why do you set the height and width in the last lines of the if blocks? After you do `height = height * ratio;` don't you then override that with `var height = $(this).height();` right outside the if block? Thanks. – ksclarke Jun 06 '16 at 16:21
11

A couple of suggestions:

  • Make this a function where you can pass in a max or min size, rather than hard-coding it; that will make it more reusable
  • If you use jQuery's .animate method, like .animate({width: maxWidth}), it should scale the other dimension for you automatically.
Nathan Long
  • 122,748
  • 97
  • 336
  • 451
  • 1
    Using the jQuery .animate method only lets you scale by one dimension. In other words, I can't set a maxWidth and maxHeight. – davekaro Apr 29 '10 at 20:23
  • 2
    @davekaro - from the docs: "We can, for example, simultaneously animate the width and height..." http://api.jquery.com/animate/ – Nathan Long Apr 30 '10 at 01:59
  • Nice catch about using .animate() like this, was totally unaware that it should scale the other dimension - keeping the aspect ratio correct for you. – Moddy Jun 27 '11 at 19:25
6

Great Start. Here's what I came up with:

$('img.resize').each(function(){
    $(this).load(function(){
        var maxWidth = $(this).width(); // Max width for the image
        var maxHeight = $(this).height();   // Max height for the image
        $(this).css("width", "auto").css("height", "auto"); // Remove existing CSS
        $(this).removeAttr("width").removeAttr("height"); // Remove HTML attributes
        var width = $(this).width();    // Current image width
        var height = $(this).height();  // Current image height

        if(width > height) {
            // Check if the current width is larger than the max
            if(width > maxWidth){
                var ratio = maxWidth / width;   // get ratio for scaling image
                $(this).css("width", maxWidth); // Set new width
                $(this).css("height", height * ratio);  // Scale height based on ratio
                height = height * ratio;    // Reset height to match scaled image
            }
        } else {
            // Check if current height is larger than max
            if(height > maxHeight){
                var ratio = maxHeight / height; // get ratio for scaling image
                $(this).css("height", maxHeight);   // Set new height
                $(this).css("width", width * ratio);    // Scale width based on ratio
                width = width * ratio;  // Reset width to match scaled image
            }
        }
    });
});

This has the benefit of allowing you to specify both width and height while allowing the image to still scale proportionally.

Tyler B
  • 308
  • 2
  • 9
5
$(function() {
  $('.mhz-news-img img').each(function() {
    var maxWidth = 320; // Max width for the image
    var maxHeight = 200;    // Max height for the image
    var maxratio=maxHeight/maxWidth;
    var width = $(this).width();    // Current image width
    var height = $(this).height();  // Current image height
    var curentratio=height/width;
    // Check if the current width is larger than the max

    if(curentratio>maxratio)
    {
        ratio = maxWidth / width;   // get ratio for scaling image
        $(this).css("width", maxWidth); // Set new width
        $(this).css("height", height *ratio); // Scale height based on ratio
    }
    else
    { 
        ratio = maxHeight / height; // get ratio for scaling image
        $(this).css("height", maxHeight);   // Set new height
        $(this).css("width", width * ratio);    // Scale width based on ratio
    }
  });
});
Miehz
  • 51
  • 1
  • 1
3
$(document).ready(function(){
    $('img').each(function(){
        var maxWidth = 660;
        var ratio = 0;
        var img = $(this);

        if(img.width() > maxWidth){
            ratio = img.height() / img.width();
            img.attr('width', maxWidth);
            img.attr('height', (maxWidth*ratio));   
        }
    });
});

that will do the magic trick for everyone using latest jquery. Be sure you set your selector right (I used $('img') but that can be different in your case). This only works for landscape mode. But if you look at it, only a few things have to be done to set it to portrait, aka, if img.height() > maxHeight) stuff

ThomasV
  • 31
  • 1
  • Image size is avalaible after load completed, so I used the code above in combination with this one and it worked nice: http://stackoverflow.com/a/3877079/733749 – g1ga Jul 09 '12 at 11:18
2

CSS:

.imgMaxWidth {
    max-width:100px;
    height:auto;
}
.imgMaxHeight {
    max-height:100px;
    width:auto;
}

HTML:

<img src="image.jpg" class="imageToResize imgMaxHeight" />

jQuery:

<script type="text/javascript">
function onLoadF() {
    $('.imageToResize').each(function() {
        var imgWidth = $(this).width();
        if (imgWidth>100) {
            $(this).removeClass("imgMaxHeight").addClass("imgMaxWidth");
        }
    });
}
window.onload = onLoadF;
</script>
2
$(function() {
    $('.story-small img').each(function() {
        var maxWidth = 100; // Max width for the image
        var maxHeight = 100;    // Max height for the image
        var width = $(this).width();    // Current image width
        var height = $(this).height();  // Current image height
        // Check if the current width is larger than the max
        if(width>height && width>maxWidth)
        {
            ratio = maxWidth / width;   // get ratio for scaling image
            $(this).css("width", maxWidth); // Set new width
            $(this).css("height", height * ratio); // Scale height based on ratio
        }
        else if(height>width && height>maxHeight)
        {
            ratio = maxHeight / height; // get ratio for scaling image
            $(this).css("height", maxHeight);   // Set new height
            $(this).css("width", width * ratio);    // Scale width based on ratio
        }
    });
});
Tim Stone
  • 19,119
  • 6
  • 56
  • 66
Osman
  • 21
  • 3
  • 1
    As a rule, always add some text explaining what you changed and why. Don't force the reader to compare each line to see what you changed and make guesses as to why your change is better. – Devon_C_Miller Nov 27 '12 at 14:14
1

You can resize image with this piece of code

    var maxWidth = 600;
    $("img").each(function () {
      var imageWidth = $(this).width();
      var imageHeight = $(this).height();
        if (imageWidth > maxWidth) {
          var percentdiff = (imageWidth - maxWidth) / imageWidth * 100;
          $(this).width(maxWidth);
          $(this).height(imageHeight - (imageHeight * percentdiff / 100));
        }
   });
0

Modifying Aleksandar's answer to make it as jquery plugin and accepts maxwidth and maxheight as arguments, suggested by Nathan.

$.fn.resize = function(maxWidth,maxHeight) {
return this.each(function() {
    var ratio = 0;
    var width = $(this).width();
    var height = $(this).height();
    if(width > maxWidth){
        ratio = maxWidth / width;
        $(this).css("width", maxWidth);
        $(this).css("height", height * ratio);
        height = height * ratio;
    }
    var width = $(this).width();
    var height = $(this).height();
    if(height > maxHeight){
        ratio = maxHeight / height;
        $(this).css("height", maxHeight);
        $(this).css("width", width * ratio);
        width = width * ratio;
    }
});
};

Used as $('.imgClass').resize(300,50);

Ahamed
  • 39,245
  • 13
  • 40
  • 68
0
function resize() {resizeFrame(elemento, margin);};

jQuery.event.add(window, "load", resize);
jQuery.event.add(window, "resize", resize);
function resizeFrame(item, marge) {
  $(item).each(function() {
  var m = marge*2;
  var mw = $(window).width()-m; 
  var mh = $(window).height()-m;
  var w = $('img',this).width();
  var h = $('img',this).height();
  var mr = mh/mw;
  var cr = h/w;
  $('img',this).css({position:'absolute',minWidth:(w-w)+20,minHeight:(h-h)+20,margin:'auto',top:'0',right:'0',bottom:'0',left:'0',padding:marge});
    if(cr < mr){
        var r = mw/w;
        $('img',this).css({width: mw});
        $('img',this).css({height: h*r});
    }else if(cr > mr){
        var r = mh/h;
        $('img',this).css({height: mh});
        $('img',this).css({width: w*r});
    }
  });  
}
0

And old post... bit still. Resizing is one thing, but it can leave resized images uncentered, and looking a bit unorganised. So I added a few lines to the original post to add a left margin to centralise any resized images.

$(".schs_bonsai_image_slider_image").each(function()
{
    var maxWidth = 787; // Max width for the image
    var maxHeight = 480;    // Max height for the image
    var ratio = 0;  // Used for aspect ratio
    var width = $(this).width();    // Current image width
    var height = $(this).height();  // Current image height

    // Check if the current width is larger than the max
    if(width > maxWidth)
    {
        ratio = maxWidth / width;   // get ratio for scaling image
        $(this).css("width", maxWidth); // Set new width
        $(this).css("height", height * ratio);  // Scale height based on ratio
        height = height * ratio;    // Reset height to match scaled image
        width = width * ratio;    // Reset width to match scaled image
    }
    // Check if current height is larger than max
    if(height > maxHeight)
    {
        ratio = maxHeight / height; // get ratio for scaling image
        $(this).css("height", maxHeight);   // Set new height
        $(this).css("width", width * ratio);    // Scale width based on ratio
        width = width * ratio;    // Reset width to match scaled image
        height = height * ratio;    // Reset height to match scaled image
    }
    var newwidth = $(this).width();
    var parentwidth=$(this).parent().width();
    var widthdiff=(parentwidth-newwidth)/2;
    $(this).css("margin-left",widthdiff);
});
Jamie Hutber
  • 26,790
  • 46
  • 179
  • 291
Gavin Simpson
  • 2,766
  • 3
  • 30
  • 39
0

So much code here, but I think this is the best answer

function resize() {
            var input = $("#picture");
            var maxWidth = 300;
            var maxHeight = 300;
            var width = input.width();
            var height = input.height();
            var ratioX = (maxWidth / width);
            var ratioY = (maxHeight / height);
            var ratio = Math.min(ratioX, ratioY);

            var newWidth  = (width * ratio);
            var newHeight = (height * ratio);
            input.css("width", newWidth);
            input.css("height", newHeight);
};
Tomás Escamez
  • 542
  • 1
  • 6
  • 17
0

You can do this with the aeimageresize jquery plugin.

https://plugins.jquery.com/ae.image.resize

https://github.com/adeelejaz/jquery-image-resize

$(function() {
    $( ".resizeme" ).aeImageResize({ height: 250, width: 250 });
});
desbest
  • 4,746
  • 11
  • 51
  • 84
-1

imgLiquid (a jQuery Plugin) seems to do what you ask.

Demo:
http://goo.gl/Wk8bU

JsFiddle example:
http://jsfiddle.net/karacas/3CRx7/#base

Javascript

$(function() {

    $(".imgLiquidFill").imgLiquid({
        fill: true,
        horizontalAlign: "center",
        verticalAlign: "top"
    });

    $(".imgLiquidNoFill").imgLiquid({
        fill: false,
        horizontalAlign: "center",
        verticalAlign: "50%"
    });
     });

Html

<div class="boxSep" >
    <div class="imgLiquidNoFill imgLiquid" style="width:250px; height:250px;">
        <img alt="" src="http://www.juegostoystory.net/files/image/2010_Toy_Story_3_USLC12_Woody.jpg"/>
    </div>
</div>
Filo
  • 2,829
  • 1
  • 21
  • 36