Saya berencana menggunakannya dengan JavaScript untuk memotong gambar agar sesuai dengan seluruh jendela.
Edit : Saya akan menggunakan komponen pihak ke-3 yang hanya menerima rasio aspek dalam format seperti: 4:3
, 16:9
.
javascript
algorithm
crop
aspect-ratio
Nathan
sumber
sumber
Jawaban:
Saya rasa Anda sedang mencari
integer:integer
solusi rasio aspek yang dapat digunakan seperti16:9
daripadafloat:1
solusi seperti1.77778:1
.Jika ya, yang perlu Anda lakukan adalah mencari pembagi persekutuan terbesar (PBT) dan membagi kedua nilai tersebut dengan itu. PBT adalah angka tertinggi yang membagi kedua angka secara merata. Jadi PBT untuk 6 dan 10 adalah 2, PBT 44 dan 99 adalah 11.
Misalnya, monitor 1024x768 memiliki GCD 256. Jika Anda membagi kedua nilai tersebut, Anda akan mendapatkan 4x3 atau 4: 3.
Algoritme GCD (rekursif):
function gcd (a,b): if b == 0: return a return gcd (b, a mod b)
Di C:
static int gcd (int a, int b) { return (b == 0) ? a : gcd (b, a%b); } int main(void) { printf ("gcd(1024,768) = %d\n",gcd(1024,768)); }
Dan inilah beberapa HTML / Javascript lengkap yang menunjukkan satu cara untuk mendeteksi ukuran layar dan menghitung rasio aspek dari itu. Ini berfungsi di FF3, saya tidak yakin dukungan apa yang dimiliki browser lain
screen.width
danscreen.height
.<html><body> <script type="text/javascript"> function gcd (a, b) { return (b == 0) ? a : gcd (b, a%b); } var w = screen.width; var h = screen.height; var r = gcd (w, h); document.write ("<pre>"); document.write ("Dimensions = ", w, " x ", h, "<br>"); document.write ("Gcd = ", r, "<br>"); document.write ("Aspect = ", w/r, ":", h/r); document.write ("</pre>"); </script> </body></html>
Ini menghasilkan (pada monitor layar lebar aneh saya):
Dimensions = 1680 x 1050 Gcd = 210 Aspect = 8:5
Orang lain yang saya uji ini:
Dimensions = 1280 x 1024 Gcd = 256 Aspect = 5:4 Dimensions = 1152 x 960 Gcd = 192 Aspect = 6:5 Dimensions = 1280 x 960 Gcd = 320 Aspect = 4:3 Dimensions = 1920 x 1080 Gcd = 120 Aspect = 16:9
Saya berharap saya memiliki yang terakhir di rumah tetapi, tidak, sayangnya ini adalah mesin kerja.
Apa yang Anda lakukan jika Anda menemukan rasio aspek tidak didukung oleh alat pengubah ukuran grafik adalah masalah lain. Saya curiga cara terbaik adalah menambahkan baris letter-boxing (seperti yang Anda dapatkan di bagian atas dan bawah TV lama Anda saat Anda menonton film layar lebar di atasnya). Saya akan menambahkannya di bagian atas / bawah atau samping (mana saja yang menghasilkan paling sedikit garis kotak surat) sampai gambar memenuhi persyaratan.
Satu hal yang mungkin ingin Anda pertimbangkan adalah kualitas gambar yang telah diubah dari 16: 9 menjadi 5: 4 - Saya masih ingat koboi kurus dan tinggi yang biasa saya tonton di masa muda saya di televisi sebelum letter-boxing diperkenalkan. Anda mungkin lebih baik memiliki satu gambar berbeda per rasio aspek dan hanya mengubah ukuran yang benar untuk dimensi layar yang sebenarnya sebelum mengirimkannya ke kabel.
sumber
728x90
->364:45
saya tidak yakin itu adalah hasil yang diinginkanjika itu yang Anda cari. Anda kemudian dapat mengalikannya dengan salah satu dimensi ruang target untuk mengetahui yang lain (yang mempertahankan rasio), mis.
sumber
Jawaban paxdiablo sangat bagus, tetapi ada banyak resolusi umum yang hanya memiliki sedikit lebih banyak atau lebih sedikit piksel ke arah tertentu, dan pendekatan pembagi umum terbesar memberikan hasil yang mengerikan bagi mereka.
Ambil contoh resolusi berperilaku baik 1360x765 yang memberikan rasio 16: 9 yang bagus menggunakan pendekatan gcd. Menurut Steam, resolusi ini hanya digunakan oleh 0,01% penggunanya, sementara 1366x768 digunakan oleh 18,9%. Mari kita lihat apa yang kita dapatkan menggunakan pendekatan gcd:
1360x765 - 16:9 (0.01%) 1360x768 - 85:48 (2.41%) 1366x768 - 683:384 (18.9%)
Kami ingin membulatkan rasio 683: 384 ke rasio terdekat, 16: 9.
Saya menulis skrip python yang mem-parsing file teks dengan nomor yang ditempel dari halaman survei Perangkat Keras Steam, dan mencetak semua resolusi dan rasio terdekat yang diketahui, serta prevalensi setiap rasio (yang merupakan tujuan saya ketika saya memulai ini):
# Contents pasted from store.steampowered.com/hwsurvey, section 'Primary Display Resolution' steam_file = './steam.txt' # Taken from http://upload.wikimedia.org/wikipedia/commons/thumb/f/f0/Vector_Video_Standards4.svg/750px-Vector_Video_Standards4.svg.png accepted_ratios = ['5:4', '4:3', '3:2', '8:5', '5:3', '16:9', '17:9'] #------------------------------------------------------- def gcd(a, b): if b == 0: return a return gcd (b, a % b) #------------------------------------------------------- class ResData: #------------------------------------------------------- # Expected format: 1024 x 768 4.37% -0.21% (w x h prevalence% change%) def __init__(self, steam_line): tokens = steam_line.split(' ') self.width = int(tokens[0]) self.height = int(tokens[2]) self.prevalence = float(tokens[3].replace('%', '')) # This part based on pixdiablo's gcd answer - http://stackoverflow.com/a/1186465/828681 common = gcd(self.width, self.height) self.ratio = str(self.width / common) + ':' + str(self.height / common) self.ratio_error = 0 # Special case: ratio is not well behaved if not self.ratio in accepted_ratios: lesser_error = 999 lesser_index = -1 my_ratio_normalized = float(self.width) / float(self.height) # Check how far from each known aspect this resolution is, and take one with the smaller error for i in range(len(accepted_ratios)): ratio = accepted_ratios[i].split(':') w = float(ratio[0]) h = float(ratio[1]) known_ratio_normalized = w / h distance = abs(my_ratio_normalized - known_ratio_normalized) if (distance < lesser_error): lesser_index = i lesser_error = distance self.ratio_error = distance self.ratio = accepted_ratios[lesser_index] #------------------------------------------------------- def __str__(self): descr = str(self.width) + 'x' + str(self.height) + ' - ' + self.ratio + ' - ' + str(self.prevalence) + '%' if self.ratio_error > 0: descr += ' error: %.2f' % (self.ratio_error * 100) + '%' return descr #------------------------------------------------------- # Returns a list of ResData def parse_steam_file(steam_file): result = [] for line in file(steam_file): result.append(ResData(line)) return result #------------------------------------------------------- ratios_prevalence = {} data = parse_steam_file(steam_file) print('Known Steam resolutions:') for res in data: print(res) acc_prevalence = ratios_prevalence[res.ratio] if (res.ratio in ratios_prevalence) else 0 ratios_prevalence[res.ratio] = acc_prevalence + res.prevalence # Hack to fix 8:5, more known as 16:10 ratios_prevalence['16:10'] = ratios_prevalence['8:5'] del ratios_prevalence['8:5'] print('\nSteam screen ratio prevalences:') sorted_ratios = sorted(ratios_prevalence.items(), key=lambda x: x[1], reverse=True) for value in sorted_ratios: print(value[0] + ' -> ' + str(value[1]) + '%')
Yang penasaran, berikut adalah prevalensi rasio layar di antara pengguna Steam (per Oktober 2012):
16:9 -> 58.9% 16:10 -> 24.0% 5:4 -> 9.57% 4:3 -> 6.38% 5:3 -> 0.84% 17:9 -> 0.11%
sumber
Saya rasa Anda ingin memutuskan mana dari 4: 3 dan 16: 9 yang paling cocok.
function getAspectRatio(width, height) { var ratio = width / height; return ( Math.abs( ratio - 4 / 3 ) < Math.abs( ratio - 16 / 9 ) ) ? '4:3' : '16:9'; }
sumber
Berikut adalah versi algoritma pendekatan rasional terbaik James Farey dengan tingkat ketidakjelasan yang dapat disesuaikan yang ditransfer ke javascript dari kode penghitungan rasio aspek aslinya ditulis dengan python.
Metode ini menggunakan float (
width/height
) dan batas atas untuk pembilang / penyebut pecahan.Dalam contoh di bawah ini saya menetapkan batas atas
50
karena saya perlu1035x582
(1.77835051546) diperlakukan sebagai16:9
(1.77777777778) daripada345:194
yang Anda dapatkan dengan polosgcd
algoritma yang tercantum dalam jawaban lain.<html> <body> <script type="text/javascript"> function aspect_ratio(val, lim) { var lower = [0, 1]; var upper = [1, 0]; while (true) { var mediant = [lower[0] + upper[0], lower[1] + upper[1]]; if (val * mediant[1] > mediant[0]) { if (lim < mediant[1]) { return upper; } lower = mediant; } else if (val * mediant[1] == mediant[0]) { if (lim >= mediant[1]) { return mediant; } if (lower[1] < upper[1]) { return lower; } return upper; } else { if (lim < mediant[1]) { return lower; } upper = mediant; } } } document.write (aspect_ratio(800 / 600, 50) +"<br/>"); document.write (aspect_ratio(1035 / 582, 50) + "<br/>"); document.write (aspect_ratio(2560 / 1440, 50) + "<br/>"); </script> </body></html>
4,3 // (1.33333333333) (800 x 600) 16,9 // (1.77777777778) (2560.0 x 1440) 16,9 // (1.77835051546) (1035.0 x 582)
sumber
Kalau-kalau Anda seorang performance freak ...
Cara tercepat (dalam JavaScript) untuk menghitung rasio persegi panjang adalah menggunakan algoritma biner Great Common Divisor sejati.
(Semua tes kecepatan dan waktu telah dilakukan oleh orang lain, Anda dapat memeriksa satu benchmark di sini: https://lemire.me/blog/2013/12/26/fastest-way-to-compute-the-greatest-common-divisor / )
Ini dia:
sumber
Ini solusi saya. Ini cukup mudah karena yang saya pedulikan belum tentu GCD atau bahkan rasio yang akurat: karena Anda mendapatkan hal-hal aneh seperti 345/113 yang tidak dapat dipahami manusia.
Saya pada dasarnya menetapkan lanskap yang dapat diterima, atau rasio potret dan "nilai" mereka sebagai pelampung ... Saya kemudian membandingkan versi pelampung rasio untuk masing-masing dan yang pernah memiliki perbedaan nilai absolut terendah adalah rasio yang paling dekat dengan item. Dengan cara itu ketika pengguna membuatnya 16: 9 tetapi kemudian menghapus 10 piksel dari bawah masih dihitung sebagai 16: 9 ...
accepted_ratios = { 'landscape': ( (u'5:4', 1.25), (u'4:3', 1.33333333333), (u'3:2', 1.5), (u'16:10', 1.6), (u'5:3', 1.66666666667), (u'16:9', 1.77777777778), (u'17:9', 1.88888888889), (u'21:9', 2.33333333333), (u'1:1', 1.0) ), 'portrait': ( (u'4:5', 0.8), (u'3:4', 0.75), (u'2:3', 0.66666666667), (u'10:16', 0.625), (u'3:5', 0.6), (u'9:16', 0.5625), (u'9:17', 0.5294117647), (u'9:21', 0.4285714286), (u'1:1', 1.0) ), } def find_closest_ratio(ratio): lowest_diff, best_std = 9999999999, '1:1' layout = 'portrait' if ratio < 1.0 else 'landscape' for pretty_str, std_ratio in accepted_ratios[layout]: diff = abs(std_ratio - ratio) if diff < lowest_diff: lowest_diff = diff best_std = pretty_str return best_std def extract_ratio(width, height): try: divided = float(width)/float(height) if divided == 1.0: return '1:1' return find_closest_ratio(divided) except TypeError: return None
sumber
Sebagai solusi alternatif untuk pencarian GCD, saya sarankan Anda untuk memeriksa sekumpulan nilai standar. Anda dapat menemukan daftarnya di Wikipedia .
sumber
Saya berasumsi Anda berbicara tentang video di sini, dalam hal ini Anda mungkin juga perlu khawatir tentang rasio aspek piksel dari video sumber. Sebagai contoh.
PAL DV hadir dalam resolusi 720x576. Yang akan terlihat seperti 4: 3. Sekarang tergantung pada rasio aspek Pixel (PAR), rasio layar bisa menjadi 4: 3 atau 16: 9.
Untuk info lebih lanjut lihat di sini http://en.wikipedia.org/wiki/Pixel_aspect_ratio
Anda bisa mendapatkan Rasio Aspek piksel Persegi, dan banyak video web adalah itu, tetapi Anda mungkin ingin berhati-hati dari kasus lain.
Semoga ini membantu
Menandai
sumber
Berdasarkan jawaban lain, berikut adalah cara saya mendapatkan angka yang saya butuhkan dengan Python;
from decimal import Decimal def gcd(a,b): if b == 0: return a return gcd(b, a%b) def closest_aspect_ratio(width, height): g = gcd(width, height) x = Decimal(str(float(width)/float(g))) y = Decimal(str(float(height)/float(g))) dec = Decimal(str(x/y)) return dict(x=x, y=y, dec=dec) >>> closest_aspect_ratio(1024, 768) {'y': Decimal('3.0'), 'x': Decimal('4.0'), 'dec': Decimal('1.333333333333333333333333333')}
sumber
Saya yakin rasio aspek adalah lebar dibagi tinggi.
sumber
Saya pikir ini melakukan apa yang Anda minta:
webdeveloper.com - desimal ke pecahan
Lebar / tinggi memberi Anda desimal, diubah menjadi pecahan dengan ":" di tempat '/' memberi Anda "rasio".
sumber
Algoritme dengan Python ini membantu Anda mencapai tujuan tersebut.
Ceritakan apa yang terjadi jika jendelanya berukuran lucu.
Mungkin yang harus Anda miliki adalah daftar semua rasio yang dapat diterima (untuk komponen pihak ke-3). Kemudian, temukan yang paling cocok dengan jendela Anda dan kembalikan rasio itu dari daftar.
sumber
sedikit cara yang aneh untuk melakukan ini tetapi menggunakan resolusi sebagai aspeknya. MISALNYA
1024: 768
atau kamu bisa mencoba
var w = screen.width; var h = screen.height; for(var i=1,asp=w/h;i<5000;i++){ if(asp*i % 1==0){ i=9999; document.write(asp*i,":",1*i); } }
sumber
function ratio(w, h) { function mdc(w, h) { var resto; do { resto = w % h; w = h; h = resto; } while (resto != 0); return w; } var mdc = mdc(w, h); var width = w/mdc; var height = h/mdc; console.log(width + ':' + height); } ratio(1920, 1080);
sumber
dalam kasus saya, saya ingin sesuatu seperti
function ratio(array){ let min = Math.min(...array); let ratio = array.map((element)=>{ return element/min; }); return ratio; } document.write(ratio([10,5,15,20,25])); // [ 2, 1, 3, 4, 5 ]
sumber
Anda selalu dapat memulai dengan membuat tabel pencarian berdasarkan rasio aspek umum. Periksa https://en.wikipedia.org/wiki/Display_aspect_ratio Kemudian Anda cukup melakukan pembagian
Untuk masalah kehidupan nyata, Anda bisa melakukan hal seperti di bawah ini
let ERROR_ALLOWED = 0.05 let STANDARD_ASPECT_RATIOS = [ [1, '1:1'], [4/3, '4:3'], [5/4, '5:4'], [3/2, '3:2'], [16/10, '16:10'], [16/9, '16:9'], [21/9, '21:9'], [32/9, '32:9'], ] let RATIOS = STANDARD_ASPECT_RATIOS.map(function(tpl){return tpl[0]}).sort() let LOOKUP = Object() for (let i=0; i < STANDARD_ASPECT_RATIOS.length; i++){ LOOKUP[STANDARD_ASPECT_RATIOS[i][0]] = STANDARD_ASPECT_RATIOS[i][1] } /* Find the closest value in a sorted array */ function findClosest(arrSorted, value){ closest = arrSorted[0] closestDiff = Math.abs(arrSorted[0] - value) for (let i=1; i<arrSorted.length; i++){ let diff = Math.abs(arrSorted[i] - value) if (diff < closestDiff){ closestDiff = diff closest = arrSorted[i] } else { return closest } } return arrSorted[arrSorted.length-1] } /* Estimate the aspect ratio based on width x height (order doesn't matter) */ function estimateAspectRatio(dim1, dim2){ let ratio = Math.max(dim1, dim2) / Math.min(dim1, dim2) if (ratio in LOOKUP){ return LOOKUP[ratio] } // Look by approximation closest = findClosest(RATIOS, ratio) if (Math.abs(closest - ratio) <= ERROR_ALLOWED){ return '~' + LOOKUP[closest] } return 'non standard ratio: ' + Math.round(ratio * 100) / 100 + ':1' }
Kemudian Anda cukup memberikan dimensi dalam urutan apa pun
estimateAspectRatio(1920, 1080) // 16:9 estimateAspectRatio(1920, 1085) // ~16:9 estimateAspectRatio(1920, 1150) // non standard ratio: 1.65:1 estimateAspectRatio(1920, 1200) // 16:10 estimateAspectRatio(1920, 1220) // ~16:10
sumber
?
sumber