Bagaimana mengubah ukuran gambar secara proporsional / menjaga rasio aspek?

167

Saya memiliki gambar yang akan cukup besar dalam dimensi dan saya ingin mengecilkannya dengan jQuery sambil menjaga proporsi dibatasi, yaitu rasio aspek yang sama.

Dapatkah seseorang mengarahkan saya ke beberapa kode, atau menjelaskan logikanya?

kobe
sumber
4
Bisakah Anda menguraikan mengapa jQuery harus digunakan? Ada solusi khusus CSS (lihat jawaban saya ): atur max-widthdan max-heightke 100%.
Dan Dascalescu
9
Kalau-kalau ada yang tidak tahu, jika Anda hanya menetapkan satu dimensi gambar (baik lebar atau tinggi) ukurannya proporsional. Sudah seperti ini sejak fajar web. Misalnya:<img src='image.jpg' width=200>
GetFree
2
Juga, Anda mungkin mempertimbangkan untuk menggunakan sesuatu seperti slimmage.js untuk menghemat bandwidth dan RAM perangkat seluler.
Sungai Lilith

Jawaban:

188

Lihatlah potongan kode ini dari http://ericjuden.com/2009/07/jquery-image-resize/

$(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
sumber
1
Maaf, melewatkan beberapa logika matematika ... ada apa saat Anda perlu meningkatkan semuanya (katakanlah, Anda meningkatkan maxHeight)?
Ben
4
Bisakah ini dilakukan dengan CSS saja? (Maks-lebar, tinggi: otomatis, dll?)
Tronathan
11
Tidak yakin mengapa jQuery diperlukan untuk ini. Mengecilkan gambar secara proporsional pada klien dapat dilakukan dengan CSS, dan itu sepele: cukup atur max-widthdan max-heightke 100%. jsfiddle.net/9EQ5c
Dan Dascalescu
10
Ini tidak dapat dilakukan dengan CSS karena Pernyataan IF. Saya percaya intinya adalah untuk mengisi gambar thumbnail. Jika gambar terlalu tinggi, itu harus lebar max, jika gambar terlalu lebar, itu harus tinggi max. Jika Anda melakukan CSS max-width, max-height, Anda akan mendapatkan thumbnail dengan spasi putih alih-alih diisi penuh
ntgCleaner
Apakah kode ini dapat menyebabkan masalah di browser, macet atau melambat ??
Déjà Bond
442

Saya pikir ini adalah metode yang sangat keren :

 /**
  * 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
sumber
33
Jawaban yang sangat superior! Jawaban yang benar jatuh datar di wajahnya jika tinggi dan lebarnya keduanya lebih besar. Sungguh, bagus, juga kumis yang bagus.
Starkers
1
Anda benar tentang @sstauross, piksel desimal dapat memiliki hasil yang sedikit tidak terduga . Namun dalam kasus penggunaan saya, itu diabaikan. Saya kira Math.floorakan sangat membantu dengan desain pixel yang sempurna :-)
Jason J. Nathan
1
Terima kasih, saya butuh ini hampir "satu-liner".
Hernan
1
Terima kasih Jason, jawaban ini sangat membantu saya.
Ashok Shah
4
Ini cara yang fantastis untuk menangani masalah ini! Saya men-tweak sedikit untuk elemen img + mencegah memperbesar gambar: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
70

Jika saya memahami pertanyaan dengan benar, Anda bahkan tidak perlu jQuery untuk ini. Mengecilkan gambar secara proporsional pada klien dapat dilakukan dengan CSS saja: cukup atur max-widthdan max-heightke 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>​

Ini biola: http://jsfiddle.net/9EQ5c/

Dan Dascalescu
sumber
2
Ini adalah jawaban yang jauh lebih mudah daripada di atas. Terima kasih. tapi bagaimana Anda mendapatkan tautan "jawaban saya" untuk menggulir ke bawah ke posting Anda?
SnareChops
@SnareChops: ini hanya sebuah jangkar HTML .
Dan Dascalescu
1
@SnareChops: jika Anda menggunakan tautan yang diberikan oleh tautan "bagikan" di bawah jawaban, itu juga akan bergulir ke jawabannya.
Flimm
1
@ Flimm Karena rentang tidak ditampilkan: blok secara default. Cukup tambahkan tampilan: blokir, atau buat div.
mahemoff
1
Dalam kasus saya IMG di-renderd dengan WordPress sehingga lebar dan tinggi diatur. Dalam CSS saya juga harus mengatur width: auto; height: auto;agar kode Anda berjalan :)
lippoliv
12

Untuk menentukan rasio aspek , Anda harus memiliki rasio untuk membidik.

Tinggi

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

Lebar

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

Dalam contoh ini saya menggunakan 16:10karena ini rasio aspek monitor yang khas.

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

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

Hasil dari di atas adalah 147dan300

Rick
sumber
Mempertimbangkan, 300 = lebar diagonal = tinggi * rasio dan tinggi sama seperti yang Anda katakan
Johny Pie
6

sebenarnya saya baru saja mengalami masalah ini dan solusi yang saya temukan anehnya sederhana dan aneh

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

dan secara ajaib gambar diubah ukurannya ke ketinggian baru dan mempertahankan rasio yang sama!

WindowsMaker
sumber
1
saya pikir ini berguna - tetapi saya kira itu tidak akan membatasi gambar jika sangat sangat luas katakan, untuk lebar maksimal ...
stephendwolff
Hal ini berfungsi saat Anda tidak mengatur atribut lainnya. (lebar dalam hal ini)
NoobishPro
4

Ada 4 parameter untuk masalah ini

  1. lebar gambar saat ini iX
  2. tinggi gambar saat ini iY
  3. target viewport lebar cX
  4. target tinggi viewport cY

Dan ada 3 parameter kondisional yang berbeda

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

larutan

  1. Temukan sisi yang lebih kecil dari port tampilan target F
  2. Temukan sisi yang lebih besar dari port tampilan saat ini L
  3. Temukan faktor kedua F / L = faktor
  4. Lipat gandakan kedua sisi port saat ini dengan faktor yaitu, fX = iX * factor; TA = iY * faktor

itu semua yang perlu kamu lakukan.

//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 ; 

Ini adalah forum yang matang, saya tidak memberi Anda kode untuk itu :)

PRASANTH KOLLAIKAL
sumber
2
Posting metode di belakang ini bagus, tetapi saya menandai Anda untuk tidak benar-benar membantu pengguna dengan memposting kode. Tampaknya sedikit mengganggu
Doidgey
6
"Bisakah seseorang menunjuk saya ke beberapa kode, atau menjelaskan logikanya?" - Jelas dia baik-baik saja dengan hanya menjelaskan metode kepadanya. Secara pribadi, saya pikir ini akan menjadi cara yang lebih baik untuk membantu seseorang, untuk membantu mereka memahami metode daripada meminta mereka menyalin dan menempelkan kode.
JessMcintosh
@JessMcintosh, kasihan bazillion suntingan untuk pertanyaan asli membuat komentar Anda di luar konteks :)
Jason J. Nathan
4

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

Browser akan menjaga rasio aspek tetap utuh.

yaitu max-widthtendangan ketika lebar gambar lebih besar dari tinggi dan tingginya akan dihitung secara proporsional. Demikian pula max-heightakan berlaku ketika tinggi lebih besar dari lebar.

Anda tidak memerlukan jQuery atau javascript untuk ini.

Didukung oleh ie7 + dan browser lainnya ( http://caniuse.com/minmaxwh ).

Sojin
sumber
Tip yang bagus! Hanya akan meletakkan CSS dalam file CSS dan tidak langsung dalam kode html.
Markus
Saya pikir masalah dengan ini adalah bahwa itu tidak akan berfungsi ketika Anda tidak tahu apa lebar maks dan tinggi maks sampai halaman dimuat. Itulah sebabnya diperlukan solusi JS. Ini biasanya terjadi pada situs yang responsif.
Jason J. Nathan
2

Ini harus berfungsi untuk gambar dengan semua kemungkinan proporsi

$(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
sumber
2

Ini koreksi jawaban Mehdiway. Lebar dan / atau tinggi baru tidak disetel ke nilai maks. Kasing uji yang baik adalah sebagai berikut (1768 x 1075 piksel): http://spacecoastsports.com/wp-content/uploads/2014/06/sportsballs1.png . (Saya tidak dapat mengomentarinya di atas karena kurangnya poin reputasi.)

  // 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
sumber
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
sumber
5
Silakan pertimbangkan untuk menambahkan penjelasan, bukan hanya kode ketika menjawab sebuah posting.
Jørgen R
1

Jika gambar proporsional maka kode ini akan mengisi pembungkus dengan gambar. Jika gambar tidak proporsional maka lebar ekstra / tinggi akan dipotong.

    <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
sumber
1

Tanpa temp-vars atau kurung tambahan.

    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;
      }

Perlu diingat: Mesin pencari tidak menyukainya, jika atribut lebar dan tinggi tidak cocok dengan gambar, tetapi mereka tidak tahu JS.

BF
sumber
1

Setelah beberapa percobaan dan kesalahan saya datang ke solusi ini:

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
sumber
1

Pengubahan ukuran dapat dicapai (mempertahankan rasio aspek) menggunakan CSS. Ini adalah jawaban yang disederhanakan lebih lanjut yang terinspirasi oleh pos Dan Dascalescu.

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"/>

buru-buru dee
sumber
1

2 Langkah:

Langkah 1) menghitung rasio lebar asli / tinggi asli Gambar.

Langkah 2) gandakan rasio original_width / original_height dengan tinggi baru yang diinginkan untuk mendapatkan lebar baru yang sesuai dengan tinggi baru.

Hitesh Ranaut
sumber
0

Masalah ini dapat diatasi dengan CSS.

.image{
 max-width:*px;
}
pemukul banoth
sumber
-4

Ini benar-benar bekerja untuk saya untuk item yang dapat ditarik - aspectRatio: true

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