Wie kann ich die Größe von Bildern proportional ändern / das Seitenverhältnis beibehalten?

170

Ich habe Bilder, deren Größe ziemlich groß sein wird, und ich möchte sie mit jQuery verkleinern, während die Proportionen eingeschränkt bleiben, dh das gleiche Seitenverhältnis.

Kann mich jemand auf einen Code verweisen oder die Logik erklären?

kobe
quelle
4
Können Sie erläutern, warum jQuery verwendet werden muss? Es gibt eine reine CSS-Lösung (siehe meine Antwort ): Setzen Sie das max-widthund max-heightauf 100%.
Dan Dascalescu
10
Nur für den Fall, dass jemand nicht weiß, ob Sie nur eine Dimension des Bildes (entweder Breite oder Höhe) festlegen, wird die Größe proportional geändert. Das ist seit den Anfängen des Webs so. Zum Beispiel:<img src='image.jpg' width=200>
GetFree
2
Sie können auch slimmage.js verwenden , um Bandbreite und RAM für mobile Geräte zu sparen.
Lilith River

Antworten:

188

Schauen Sie sich diesen Code von http://ericjuden.com/2009/07/jquery-image-resize/ an.

$(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
            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
        }
    });
});
Moin Zaman
quelle
1
Entschuldigung, es fehlt eine mathematische Logik… was ist los, wenn Sie alles erhöhen müssen (sagen wir, Sie erhöhen maxHeight)?
Ben
4
Kann das nur mit CSS gemacht werden? (maximale Breite, Höhe: Auto usw.?)
Tronathan
11
Ich bin mir nicht sicher, warum jQuery dafür benötigt wird. Das proportionale Verkleinern des Bildes auf dem Client kann mit CSS erfolgen, und es ist trivial: Setzen Sie einfach das max-widthund max-heightauf 100%. jsfiddle.net/9EQ5c
Dan Dascalescu
10
Dies ist mit CSS aufgrund der IF-Anweisung nicht möglich. Ich glaube, es geht darum, das Miniaturbild auszufüllen. Wenn das Bild zu groß ist, muss es die maximale Breite haben, wenn das Bild zu breit ist, muss es die maximale Höhe haben. Wenn Sie CSS max-width, max-height
ausführen
Kann dieser Code Probleme in Browsern verursachen, abstürzen oder verlangsamt werden?
Déjà Bond
468

Ich denke, das ist eine wirklich coole Methode :

 /**
  * Conserve aspect ratio of the original region. Useful when shrinking/enlarging
  * images to fit into a certain area.
  *
  * @param {Number} srcWidth width of source image
  * @param {Number} srcHeight height of source image
  * @param {Number} maxWidth maximum available width
  * @param {Number} maxHeight maximum available height
  * @return {Object} { width, height }
  */
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {

    var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);

    return { width: srcWidth*ratio, height: srcHeight*ratio };
 }
Jason J. Nathan
quelle
38
Sehr überlegene Antwort! Die richtige Antwort fällt flach ins Gesicht, wenn sowohl die Höhe als auch die Breite größer sind. Wirklich gut, auch schöner Schnurrbart.
Starkers
+1 es ist ziemlich ordentlich. Was ist mit dem Deklarieren der Funktion wie function calculateAspectRatioFit(dimensions) { /* then use such as dimensions.maxWidth , dimensions.srcWidth ...*/ }und dem anschließenden Aufrufen von function({ maxWidth: someWidth, srcWidth: someOtherWith, maxHeight: someHeight, srcHeight: someOtherHeight });? Dies kann nützlich sein, um Probleme mit der Parameterreihenfolge zu vermeiden.
Adrien Be
Das wäre ideal @AdrienBe, aber diese Frage wurde vor mehr als einem Jahr beantwortet und ich denke, es ist einfach genug, um sich an persönliche Anpassungen anzupassen. :)
Jason J. Nathan
1
Sie haben Recht mit @sstauross, Dezimalpixel können leicht unerwartete Ergebnisse haben . In meinem Anwendungsfall war es jedoch vernachlässigbar. Ich nehme Math.floorwirklich helfen wird mit einem Pixel perfekt design :-)
Jason J. Nathan
6
Dies ist eine fantastische Möglichkeit, dieses Problem zu lösen! Ich habe es ein wenig für img Elemente optimiert + verhindern, dass das Bild vergrößert wird:function imgSizeFit(img, maxWidth, maxHeight){ var ratio = Math.min(1, maxWidth / img.naturalWidth, maxHeight / img.naturalHeight); img.style.width = img.naturalWidth * ratio + 'px'; img.style.height = img.naturalHeight * ratio + 'px'; }
Oriadam
73

Wenn ich die Frage richtig verstehe, brauchen Sie dafür nicht einmal jQuery. Das proportionale Verkleinern des Bildes auf dem Client kann nur mit CSS erfolgen: Stellen Sie einfach das max-widthund max-heightauf ein 100%.

<div style="height: 100px">
<img src="http://www.getdigital.de/images/produkte/t4/t4_css_sucks2.jpg"
    style="max-height: 100%; max-width: 100%">
</div>

Hier ist die Geige: http://jsfiddle.net/9EQ5c/

Dan Dascalescu
quelle
2
Dies ist eine viel einfachere Antwort als oben. Vielen Dank. Übrigens, wie haben Sie den Link "Meine Antwort" erhalten, um zu Ihrem Beitrag zu scrollen?
SnareChops
@ SnareChops: Es ist einfach ein HTML-Anker .
Dan Dascalescu
1
@SnareChops: Wenn Sie den Link verwenden, der durch den Link "Teilen" unter der Antwort angegeben wird, wird auch zur Antwort gescrollt.
Flimm
1
@Flimm Da Bereiche nicht angezeigt werden: Standardmäßig blockieren. Fügen Sie einfach display: block hinzu oder machen Sie es zu einem div.
Mahemoff
1
In meinem Fall wurde der IMG mit WordPress gerendert, sodass Breite und Höhe eingestellt wurden. In CSS musste ich auch einstellen width: auto; height: auto;, um Ihren Code zum Laufen zu bringen :)
lippoliv
12

Um das Seitenverhältnis zu bestimmen , benötigen Sie ein anzustrebendes Verhältnis.

Höhe

function getHeight(length, ratio) {
  var height = ((length)/(Math.sqrt((Math.pow(ratio, 2)+1))));
  return Math.round(height);
}

Breite

function getWidth(length, ratio) {
  var width = ((length)/(Math.sqrt((1)/(Math.pow(ratio, 2)+1))));
  return Math.round(width);
}

In diesem Beispiel verwende ich 16:10seitdem das typische Monitor-Seitenverhältnis.

var ratio = (16/10);
var height = getHeight(300,ratio);
var width = getWidth(height,ratio);

console.log(height);
console.log(width);

Ergebnisse von oben wären 147und300

Rick
quelle
In Anbetracht dessen ist 300 = diagonale Breite = Höhe * Verhältnis und Höhe dasselbe wie Sie sagten
Johny Pie
6

Eigentlich bin ich gerade auf dieses Problem gestoßen und die Lösung, die ich gefunden habe, war seltsam einfach und seltsam

$("#someimage").css({height:<some new height>})

und auf wundersame Weise wird das Bild auf die neue Höhe angepasst und das gleiche Verhältnis beibehalten!

WindowsMaker
quelle
1
Ich denke, das ist nützlich - aber ich nehme an, es wird das Bild nicht einschränken, wenn es sehr, sehr breit ist, sagen wir, auf eine maximale Breite ...
stephendwolff
Dieses Zeug funktioniert, wenn Sie das andere Attribut nicht festlegen. (Breite in diesem Fall)
NoobishPro
4

Es gibt 4 Parameter für dieses Problem

  1. aktuelle Bildbreite iX
  2. aktuelle Bildhöhe iY
  3. Breite des Zielansichtsfensters cX
  4. Höhe des Zielansichtsfensters cY

Und es gibt 3 verschiedene bedingte Parameter

  1. cX> cY?
  2. iX> cX?
  3. iY> cY?

Lösung

  1. Suchen Sie die kleinere Seite des Zielansichtsports F.
  2. Suchen Sie die größere Seite des aktuellen Ansichtsfensters L.
  3. Finden Sie den Faktor von beiden F / L = Faktor
  4. Multiplizieren Sie beide Seiten des aktuellen Ports mit dem Faktor fX = iX * -Faktor; fY = iY * -Faktor

das ist alles was du tun musst.

//Pseudo code


iX;//current width of image in the client
iY;//current height of image in the client
cX;//configured width
cY;//configured height
fX;//final width
fY;//final height

1. check if iX,iY,cX,cY values are >0 and all values are not empty or not junk

2. lE = iX > iY ? iX: iY; //long edge

3. if ( cX < cY )
   then
4.      factor = cX/lE;     
   else
5.      factor = cY/lE;

6. fX = iX * factor ; fY = iY * factor ; 

Dies ist ein ausgereiftes Forum, ich gebe dir keinen Code dafür :)

PRASANTH KOLLAIKAL
quelle
2
Das Posten der Methode dahinter ist großartig, aber ich markiere Sie dafür, dass Sie dem Benutzer nicht wirklich helfen, indem Sie Code posten. Scheint ein wenig hinderlich
Doidgey
6
"Kann mich jemand auf einen Code verweisen oder die Logik erklären?" - Offensichtlich war es ihm recht, sich nur die Methode erklären zu lassen. Persönlich denke ich, dass dies der bessere Weg wäre, jemandem zu helfen, ihm zu helfen, die Methoden zu verstehen, anstatt ihn Code kopieren und einfügen zu lassen.
JessMcintosh
@ JessMcintosh, schade, dass die bazillion Änderungen an der ursprünglichen Frage Ihren Kommentar aus dem Zusammenhang gerissen haben :)
Jason J. Nathan
4

Hilft das <img src="/path/to/pic.jpg" style="max-width:XXXpx; max-height:YYYpx;" >?

Der Browser sorgt dafür, dass das Seitenverhältnis erhalten bleibt.

dh max-widthtritt ein, wenn die Bildbreite größer als die Höhe ist und ihre Höhe proportional berechnet wird. Ähnliches max-heightgilt, wenn die Höhe größer als die Breite ist.

Sie benötigen hierfür weder jQuery noch Javascript.

Unterstützt von ie7 + und anderen Browsern ( http://caniuse.com/minmaxwh ).

Sojin
quelle
Toller Tipp! Würde das CSS einfach in eine CSS-Datei und nicht direkt in den HTML-Code einfügen.
Mark
Ich denke, das Problem dabei ist, dass es nicht funktioniert, wenn Sie nicht wissen, wie breit und wie hoch die maximale Höhe ist, bis die Seite geladen wird. Deshalb wird eine JS-Lösung benötigt. Dies ist normalerweise bei reaktionsfähigen Websites der Fall.
Jason J. Nathan
2

Dies sollte für Bilder mit allen möglichen Proportionen funktionieren

$(document).ready(function() {
    $('.list img').each(function() {
        var maxWidth = 100;
        var maxHeight = 100;
        var width = $(this).width();
        var height = $(this).height();
        var ratioW = maxWidth / width;  // Width ratio
        var ratioH = maxHeight / height;  // Height ratio

        // If height ratio is bigger then we need to scale height
        if(ratioH > ratioW){
            $(this).css("width", maxWidth);
            $(this).css("height", height * ratioW);  // Scale height according to width ratio
        }
        else{ // otherwise we scale width
            $(this).css("height", maxHeight);
            $(this).css("width", height * ratioH);  // according to height ratio
        }
    });
});
Ajjaah
quelle
2

Hier ist eine Korrektur zu Mehdiways Antwort. Die neue Breite und / oder Höhe wurde nicht auf den Maximalwert eingestellt. Ein guter Testfall ist der folgende (1768 x 1075 Pixel): http://spacecoastsports.com/wp-content/uploads/2014/06/sportsballs1.png . (Ich konnte es oben nicht kommentieren, da es an Reputationspunkten mangelte.)

  // Make sure image doesn't exceed 100x100 pixels
  // note: takes jQuery img object not HTML: so width is a function
  // not a property.
  function resize_image (image) {
      var maxWidth = 100;           // Max width for the image
      var maxHeight = 100;          // Max height for the image
      var ratio = 0;                // Used for aspect ratio

      // Get current dimensions
      var width = image.width()
      var height = image.height(); 
      console.log("dimensions: " + width + "x" + height);

      // If the current width is larger than the max, scale height
      // to ratio of max width to current and then set width to max.
      if (width > maxWidth) {
          console.log("Shrinking width (and scaling height)")
          ratio = maxWidth / width;
          height = height * ratio;
          width = maxWidth;
          image.css("width", width);
          image.css("height", height);
          console.log("new dimensions: " + width + "x" + height);
      }

      // If the current height is larger than the max, scale width
      // to ratio of max height to current and then set height to max.
      if (height > maxHeight) {
          console.log("Shrinking height (and scaling width)")
          ratio = maxHeight / height;
          width = width * ratio;
          height = maxHeight;
          image.css("width", width);
          image.css("height", height);
          console.log("new dimensions: " + width + "x" + height);
      }
  }
Tom O'Hara
quelle
2
$('#productThumb img').each(function() {
    var maxWidth = 140; // Max width for the image
    var maxHeight = 140;    // 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 > height){
        height = ( height / width ) * maxHeight;

    } else if(height > width){
        maxWidth = (width/height)* maxWidth;
    }
    $(this).css("width", maxWidth); // Set new width
    $(this).css("height", maxHeight);  // Scale height based on ratio
});
Khalid Khan
quelle
5
Bitte fügen Sie eine Erklärung hinzu, nicht nur Code, wenn Sie einen Beitrag beantworten.
Jørgen R
1

Wenn das Bild verhältnismäßig ist, füllt dieser Code den Wrapper mit Bild. Wenn das Bild nicht proportional ist, wird zusätzliche Breite / Höhe zugeschnitten.

    <script type="text/javascript">
        $(function(){
            $('#slider img').each(function(){
                var ReqWidth = 1000; // Max width for the image
                var ReqHeight = 300; // 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 && height < ReqHeight) {

                    $(this).css("min-height", ReqHeight); // Set new height
                }
                else 
                    if (width > height && width < ReqWidth) {

                        $(this).css("min-width", ReqWidth); // Set new width
                    }
                    else 
                        if (width > height && width > ReqWidth) {

                            $(this).css("max-width", ReqWidth); // Set new width
                        }
                        else 
                            (height > width && width < ReqWidth)
                {

                    $(this).css("min-width", ReqWidth); // Set new width
                }
            });
        });
    </script>
Anu
quelle
1

Ohne zusätzliche Temp-Vars oder Klammern.

    var width= $(this).width(), height= $(this).height()
      , maxWidth=100, maxHeight= 100;

    if(width > maxWidth){
      height = Math.floor( maxWidth * height / width );
      width = maxWidth
      }
    if(height > maxHeight){
      width = Math.floor( maxHeight * width / height );
      height = maxHeight;
      }

Denken Sie daran: Suchmaschinen mögen es nicht, wenn das Attribut width und height nicht zum Bild passt, sie aber JS nicht kennen.

BF
quelle
1

Nach einigem Ausprobieren kam ich zu dieser Lösung:

function center(img) {
    var div = img.parentNode;
    var divW = parseInt(div.style.width);
    var divH = parseInt(div.style.height);
    var srcW = img.width;
    var srcH = img.height;
    var ratio = Math.min(divW/srcW, divH/srcH);
    var newW = img.width * ratio;
    var newH = img.height * ratio;
    img.style.width  = newW + "px";
    img.style.height = newH + "px";
    img.style.marginTop = (divH-newH)/2 + "px";
    img.style.marginLeft = (divW-newW)/2 + "px";
}
Roland Hentschel
quelle
1

Die Größenänderung kann mithilfe von CSS erreicht werden (Beibehaltung des Seitenverhältnisses). Dies ist eine weitere vereinfachte Antwort, die von Dan Dascalescus Beitrag inspiriert wurde.

http://jsbin.com/viqare

img{
     max-width:200px;
 /*Or define max-height*/
  }
<img src="http://e1.365dm.com/13/07/4-3/20/alastair-cook-ashes-profile_2967773.jpg"  alt="Alastair Cook" />

<img src="http://e1.365dm.com/13/07/4-3/20/usman-khawaja-australia-profile_2974601.jpg" alt="Usman Khawaja"/>

Rush Dee
quelle
1

2 Schritte:

Schritt 1) ​​Berechnen Sie das Verhältnis der ursprünglichen Breite / ursprünglichen Höhe des Bildes.

Schritt 2) Multiplizieren Sie das Verhältnis original_width / original_height mit der neuen gewünschten Höhe, um die neue Breite zu erhalten, die der neuen Höhe entspricht.

Hitesh Ranaut
quelle
0

Dieses Problem kann durch CSS gelöst werden.

.image{
 max-width:*px;
}
Banoth Ravinder
quelle
0

Passen Sie die Größe an den Container an, erhalten Sie den Skalierungsfaktor und verkleinern Sie die prozentuale Kontrolle

 $(function () {
            let ParentHeight = 200;
            let ParentWidth = 300;
            $("#Parent").width(ParentWidth).height(ParentHeight);
            $("#ParentHeight").html(ParentHeight);
            $("#ParentWidth").html(ParentWidth);

            var RatioOfParent = ParentHeight / ParentWidth;
            $("#ParentAspectRatio").html(RatioOfParent);

            let ChildHeight = 2000;
            let ChildWidth = 4000;
            var RatioOfChild = ChildHeight / ChildWidth;
            $("#ChildAspectRatio").html(RatioOfChild);

            let ScaleHeight = ParentHeight / ChildHeight;
            let ScaleWidth = ParentWidth / ChildWidth;
            let Scale = Math.min(ScaleHeight, ScaleWidth);

            $("#ScaleFactor").html(Scale);
            // old scale
            //ChildHeight = ChildHeight * Scale;
            //ChildWidth = ChildWidth * Scale;

            // reduce scale by 10%, you can change the percentage
            let ScaleDownPercentage = 10;
            let CalculatedScaleValue = Scale * (ScaleDownPercentage / 100);
            $("#CalculatedScaleValue").html(CalculatedScaleValue);

            // new scale
            let NewScale = (Scale - CalculatedScaleValue);
            ChildHeight = ChildHeight * NewScale;
            ChildWidth = ChildWidth * NewScale;

            $("#Child").width(ChildWidth).height(ChildHeight);
            $("#ChildHeight").html(ChildHeight);
            $("#ChildWidth").html(ChildWidth);

        });
        #Parent {
            background-color: grey;
        }

        #Child {
            background-color: red;
        }
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Parent">
    <div id="Child"></div>
</div>

<table>
    <tr>
        <td>Parent Aspect Ratio</td>
        <td id="ParentAspectRatio"></td>
    </tr>
    <tr>
        <td>Child Aspect Ratio</td>
        <td id="ChildAspectRatio"></td>
    </tr>
    <tr>
        <td>Scale Factor</td>
        <td id="ScaleFactor"></td>
    </tr>
    <tr>
        <td>Calculated Scale Value</td>
        <td id="CalculatedScaleValue"></td>
    </tr>
    <tr>
        <td>Parent Height</td>
        <td id="ParentHeight"></td>
    </tr>
    <tr>
        <td>Parent Width</td>
        <td id="ParentWidth"></td>
    </tr>
    <tr>
        <td>Child Height</td>
        <td id="ChildHeight"></td>
    </tr>
    <tr>
        <td>Child Width</td>
        <td id="ChildWidth"></td>
    </tr>
</table>

Arun Prasad ES
quelle
-4

Das hat bei mir für einen ziehbaren Gegenstand total funktioniert - AspektRatio: wahr

.appendTo(divwrapper).resizable({
    aspectRatio: true,
    handles: 'se',
    stop: resizestop 
})
Catherine
quelle