2009-07-27 6 views
59

मैं पूरी विंडो में फिट करने के लिए एक छवि को फसल करने के लिए जावास्क्रिप्ट के साथ इसका उपयोग करने की योजना बना रहा हूं।पहलू अनुपात की गणना करने के लिए एल्गोरिदम क्या है? मुझे आउटपुट की आवश्यकता है जैसे: 4: 3, 16: 9

संपादित करें: 4: 3, 16: 9

+0

ऐसा लगता है कि वहाँ इस सवाल में एक लापता टुकड़ा है की तरह। यदि आप पहले ही स्रोत पहलू अनुपात को जानते हैं .. q का शीर्षक मुझे समझ में नहीं आता है। – Gishu

+0

मैंने इसे ठीक किया। :) – Nathan

+0

जब आप "विंडो" कहते हैं, तो क्या आपका मतलब है "स्क्रीन?" – Nosredna

उत्तर

157

मैं आपको एक प्रयोग करने योग्य पहलू अनुपात के लिए देख रहे integer:integer16:9 बजाय एक float:1 समाधान 1.77778:1 की तरह की तरह समाधान इकट्ठा होते हैं।

यदि हां, तो आपको सबसे बड़ा आम divisor (जीसीडी) मिलना चाहिए और उसके द्वारा दोनों मूल्यों को विभाजित करना है। जीसीडी उच्चतम संख्या है जो समान रूप से दोनों संख्याओं को विभाजित करती है। तो 6 और 10 के लिए जीसीडी 2 है, 44 और 99 के लिए जीसीडी 11.

उदाहरण के लिए, 1024x768 मॉनीटर में 256 का जीसीडी है। जब आप दोनों मानों को विभाजित करते हैं तो आपको 4x3 या 4: 3 मिलता है।

ए (पुनरावर्ती) GCD एल्गोरिथ्म:

function gcd (a,b): 
    if b == 0: 
     return a 
    return gcd (b, a mod b) 

सी में:

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

और यहाँ कुछ पूरा HTML/जावास्क्रिप्ट जो एक तरह से स्क्रीन आकार का पता लगाने और से पहलू अनुपात की गणना करने के पता चलता है उस। यह एफएफ 3 में काम करता है, मुझे यकीन है कि अन्य ब्राउज़रों के पास screen.width और screen.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> 

यह (मेरे अजीब चौड़ी स्क्रीन मॉनिटर पर) आउटपुट:

Dimensions = 1680 x 1050 
Gcd  = 210 
Aspect  = 8:5 

दूसरों है कि मैं इस पर परीक्षण किया:

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 

काश मैं था कि घर पर पिछले एक लेकिन , नहीं, यह दुर्भाग्य से एक काम मशीन है।

यदि आप पाते हैं कि पहलू अनुपात आपके ग्राफ़िक आकार के उपकरण द्वारा समर्थित नहीं है तो आप क्या करते हैं एक और मामला है। मुझे सबसे अच्छा शर्त है कि लेटर-मुक्केबाजी लाइनों को जोड़ना होगा (जैसे आप अपने पुराने टीवी के शीर्ष और निचले हिस्से में प्राप्त करते हैं, जब आप उस पर एक विस्तृत स्क्रीन मूवी देख रहे हों)। जब तक छवि आवश्यकताओं को पूरा नहीं करती है, तब तक मैं उन्हें ऊपर/नीचे या किनारों (जो भी कम से कम अक्षर-बॉक्सिंग लाइनों में परिणाम देता है) में जोड़ता हूं।

एक चीज जिसे आप विचार करना चाहते हैं वह एक तस्वीर की गुणवत्ता है जो 16: 9 से 5: 4 में बदल दी गई है - मुझे अभी भी अविश्वसनीय रूप से लंबा, पतला काउबॉय याद है जो मैं अपने युवाओं में टेलीविजन पर पत्र से पहले देखता था- मुक्केबाजी शुरू की गई थी।आप एक अलग छवि प्रति पहलू अनुपात होने से बेहतर हो सकते हैं और तार को भेजने से पहले वास्तविक स्क्रीन आयामों के लिए सही आकार का आकार बदल सकते हैं।

+1

यह पहला जवाब था जिसे मैंने देने का सोचा था, लेकिन मैं चिंतित था कि यह परिणाम उनके तीसरे पक्ष के घटक के लिए उपयोगी नहीं होगा अगर उसकी खिड़की का आकार 1021x711 जैसा कुछ है, उदाहरण के लिए। – Nosredna

+1

एक ओवरकिल की तरह लगता है। और यह नोस्रेना के मामलों के लिए काम नहीं करता है। मेरे पास सन्निकटन के आधार पर एक समाधान है। –

+1

मेरे ग्राहक ने मुझे बताया कि उसे दर्शक के पहलू अनुपात की आवश्यकता है। यह एक प्रिंट दुकान के लिए एक सेवा है।आंकड़ों के लिए मुझे लगता है कि – Nathan

0
Width/Height 

मैं एक 3 हिस्सा घटक है कि केवल की तरह प्रारूप में पहलू अनुपात को स्वीकार करता है का उपयोग किया जाएगा?

+0

में चारों ओर घूम रहा था, मैं एक घटक का उपयोग करूँगा जो केवल पहलू अनुपात को स्वीकार करता है जैसे: 4: 3, 16: 9 – Nathan

31
Aspect Ratio = width/height 

यदि आप यही कर रहे हैं तो यही है। इसके बाद आप दूसरे स्थान को खोजने के लिए लक्ष्य स्थान के आयामों में से एक द्वारा गुणा कर सकते हैं (जो अनुपात को बनाए रखता है) उदा।

widthT = heightT * Aspect Ratio 
heightT = widthT/Aspect Ratio 
0

मेरा मानना ​​है कि पहलू अनुपात चौड़ाई से विभाजित है।

r = w/h 
1

मैं इस करता है लगता है कि आप के लिए क्या पूछ रहे हैं:

webdeveloper.com - decimal to fraction

चौड़ाई/ऊंचाई आप एक दशमलव हो जाता है, के साथ एक अंश के लिए परिवर्तित ":" के स्थान पर '/' आप एक "अनुपात देता है "।

1

This algorithm in Python आपको वहां से रास्ते का हिस्सा बन जाता है।


मुझे बताएं कि क्या होता है यदि खिड़कियां एक मजेदार आकार है।

शायद आपके पास क्या होना चाहिए सभी स्वीकार्य अनुपात (तृतीय पक्ष घटक के लिए) की एक सूची है। फिर, अपनी खिड़की के सबसे नज़दीकी मैच को ढूंढें और सूची से उस अनुपात को वापस कर दें।

10

मुझे लगता है कि आप यह तय करना चाहते हैं कि कौन सा 4: 3 और 16: 9 सबसे अच्छा फिट है।

function getAspectRatio(width, height) { 
    var ratio = width/height; 
    return (Math.abs(ratio - 4/3) < Math.abs(ratio - 16/9)) ? '4:3' : '16:9'; 
} 
+1

जबकि आपका समाधान 4x3 और 16x9 के लिए ठीक है, ऐसा लगता है कि यह सभी संभावित पहलू अनुपात का समर्थन नहीं करेगा (हालांकि शायद यह ओपी के लिए महत्वपूर्ण नहीं है)। उदाहरण के लिए, अधिकांश विस्तृत स्क्रीन मॉनीटर का अनुपात 16x10 (1920x1200, 1600x1000) है? – Falaina

+0

हमारे पास वास्तव में प्रश्न का उत्तर देने के लिए पर्याप्त जानकारी नहीं है। :-) – Nosredna

+0

धन्यवाद! इसने एकदम जादू की तरह काम किया! – moeiscool

1

जीसीडी खोज के वैकल्पिक समाधान के रूप में, मैं आपको मानक मूल्यों के एक सेट के खिलाफ जांच करने का सुझाव देता हूं। आप Wikipedia पर एक सूची पा सकते हैं।

1

मैं यहां वीडियो के बारे में आपकी बात मानता हूं, इस मामले में आपको स्रोत वीडियो के पिक्सेल पहलू अनुपात के बारे में भी चिंता करने की आवश्यकता हो सकती है। उदाहरण के लिए।

पाल डीवी 720x576 के संकल्प में आता है। जो इसकी 4: 3 की तरह दिखेगा। अब पिक्सेल पहलू अनुपात (PAR) के आधार पर स्क्रीन अनुपात या तो 4: 3 या 16: 9 हो सकता है।

अधिक जानकारी के लिए आप वर्ग पिक्सेल पहलू अनुपात प्राप्त कर सकते हैं यहाँ http://en.wikipedia.org/wiki/Pixel_aspect_ratio

एक नजर है, और वेब वीडियो का एक बहुत है कि है, लेकिन आप अन्य मामलों से बाहर देखने के लिए कर सकते हैं।

आशा इस मदद करता है ऐसा करने लेकिन पहलू के रूप में उपयोग करने के लिए संकल्प एक अजीब तरीके से

मार्क

0

बिट। ईजी

1024: 768

या आप कोशिश कर सकते हैं

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); 
    } 
} 
+0

http://jsbin.com/amafad/1/edit मैंने आपके कोड की कोशिश की, और यह काम नहीं किया .. – JasonWyatt

11

paxdiablo के जवाब महान है, लेकिन आम प्रस्तावों किसी दिए गए दिशा में बस कुछ ही कम या ज्यादा पिक्सल है की एक बहुत कुछ कर रहे हैं, और सबसे बड़ा आम विभाजक दृष्टिकोण उन्हें भयानक परिणाम देता है।

उदाहरण के लिए 1360x765 का अच्छी तरह से व्यवहार किया गया संकल्प लें जो जीसीडी दृष्टिकोण का उपयोग करके अच्छा 16: 9 अनुपात देता है। भाप के अनुसार, इस संकल्प का उपयोग केवल 0.01% उपयोगकर्ताओं द्वारा किया जाता है, जबकि 1366x768 का उपयोग 18.9% तक किया जाता है। चलो हम क्या gcd दृष्टिकोण का उपयोग कर पाने देखें: निकटतम करने के लिए 384 अनुपात 16: 9 अनुपात

1360x765 - 16:9 (0.01%) 
1360x768 - 85:48 (2.41%) 
1366x768 - 683:384 (18.9%) 

हम जानते हैं कि 683 को ख़त्म कर करना चाहते हैं।

मैंने एक पायथन लिपि लिखी है जो स्टीम हार्डवेयर सर्वेक्षण पृष्ठ से चिपकाए गए नंबरों के साथ एक टेक्स्ट फ़ाइल को पार करती है, और सभी संकल्पों और निकटतम ज्ञात अनुपातों के साथ-साथ प्रत्येक अनुपात के प्रसार को प्रिंट करती है (जो मेरा लक्ष्य था जब मैंने इसे शुरू किया):

# 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]) + '%') 

उत्सुक के लिए, ये (स्टीम उपयोगकर्ताओं के बीच स्क्रीन अनुपात के प्रसार कर रहे हैं अक्टूबर के रूप में 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% 
1

अन्य उत्तर के आधार पर, यहाँ मैं कैसे संख्या मिल गया है मुझे पायथन में चाहिए;

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')} 
0

यहाँ मेरी हल है यह बहुत सीधे आगे के बाद से सभी मैं के बारे में परवाह जरूरी GCD या यहाँ तक कि सही अनुपात नहीं है: क्योंकि तब आप 345/113 की तरह अजीब बातें जो मानव सुबोध नहीं हैं।

मैं मूल रूप से स्वीकार्य परिदृश्य, या चित्र अनुपात और उनके "मूल्य" को एक फ्लोट के रूप में सेट करता हूं ... फिर मैं अनुपात के अपने फ्लोट संस्करण की तुलना प्रत्येक से करता हूं और जिनके पास सबसे कम पूर्ण मूल्य अंतर होता है, यह अनुपात निकटतम अनुपात है आइटम। इस तरह उपयोगकर्ता यह बनाता है 16 जब: 9, लेकिन फिर नीचे से 10 पिक्सल को हटा यह अभी भी मायने रखता है के रूप में 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' 
     else: 
      return find_closest_ratio(divided) 
    except TypeError: 
     return None 
0

यहाँ की समायोज्य स्तर के साथ जेम्स Farey के सबसे अच्छा तर्कसंगत सन्निकटन एल्गोरिथ्म के एक संस्करण है मूल रूप से अजगर में लिखे गए aspect ratio calculation code से जावास्क्रिप्ट को चित्रित किया गया अस्पष्टता।

विधि एक फ्लोट (width/height) और अंश संख्याकर्ता/denominator के लिए ऊपरी सीमा लेता है।

उदाहरण में नीचे मैं 50 की एक ऊपरी सीमा की स्थापना कर रहा हूँ क्योंकि मैं 1035x582 (1,77835051546) 16:9 (1,77777777778) के बजाय 345:194 जो आप अन्य उत्तर में सूचीबद्ध सादा gcd एल्गोरिथ्म के साथ मिल के रूप में इलाज किया जाना चाहिए।

<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) 
संबंधित मुद्दे