2012-11-15 51 views
8

मैं फ़ाइल आकार में किसी भी अपलोड किए गए चित्रों 500KB से कम संपीड़ित करने के लिए एक आवश्यकता है, मैं गूगल पर खोज की है और सभी मैं देख सकता है:पायथन छवि पुस्तकालय (पीआईएल), वांछित फ़ाइल आकार में छवि को कैसे संपीड़ित करें?

>>> foo = foo.resize((160,300),Image.ANTIALIAS) 
>>> foo.save("path\\to\\save\\image_scaled.jpg",quality=95) 

अगर मैं इस दृष्टिकोण के साथ जाना मैं अगर जाँच करने के लिए होगा संपीड़न के बाद छवि 500kb से कम है, यदि नहीं तो कम गुणवत्ता और आकार के लिए जाएं।

क्या ऐसा करने का कोई बेहतर तरीका है?

+1

यह गुणवत्ता खोज बाइनरी में है क्या करने के लिए एक बेहतर तरीका हो रही होगी। तो 50% गुणवत्ता के साथ शुरू करें, फिर आकार की जांच करें, यदि यह बहुत छोटा है तो 75% कोशिश करें, अन्यथा 25% कोशिश करें, आदि। आप 500 केबी तक जितना संभव हो उतना करीब मिलेंगे, आप अतिरिक्त अतिरिक्त पैरामीटर सेट कर सकते हैं, उदाहरण के लिए। न्यूनतम गुणवत्ता या आकार सहिष्णुता। आपको अधिकतम 7 पुनरावृत्तियों में सही संपीड़न स्तर में शून्य करने में सक्षम होना चाहिए। –

उत्तर

9

जेपीईजी संपीड़न पहले से अनुमानित नहीं है। आपके द्वारा वर्णित विधि, & माप & फिर से प्रयास करें, मुझे पता है कि एकमात्र तरीका है।

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

आप save फ़ंक्शन पर फ़ाइल जैसी ऑब्जेक्ट भी पास कर सकते हैं जो डिस्क पर लिखने के लिए परेशान नहीं है, बस बाइट्स की गणना करता है। एक बार जब आप सर्वोत्तम सेटिंग्स निर्धारित कर लेंगे तो आप इसे फिर से एक वास्तविक फ़ाइल में सहेज सकते हैं।

संपादित करें: यहां एक उपयुक्त बाइट गिनती फ़ाइल ऑब्जेक्ट का कार्यान्वयन है। सहेजने के बाद बस size देखें।

class file_counter(object): 
    def __init__(self): 
     self.position = self.size = 0 

    def seek(self, offset, whence=0): 
     if whence == 1: 
      offset += self.position 
     elif whence == 2: 
      offset += self.size 
     self.position = min(offset, self.size) 

    def tell(self): 
     return self.position 

    def write(self, string): 
     self.position += len(string) 
     self.size = max(self.size, self.position) 

संपादित करें 2: यहाँ एक द्विआधारी खोज के ऊपर का उपयोग कर प्रयास की सबसे छोटी संख्या में इष्टतम quality प्राप्त करने के लिए है।

def smaller_than(im, size, guess=70, subsampling=1, low=1, high=100): 
    while low < high: 
     counter = file_counter() 
     im.save(counter, format='JPEG', subsampling=subsampling, quality=guess) 
     if counter.size < size: 
      low = guess 
     else: 
      high = guess - 1 
     guess = (low + high + 1) // 2 
    return low 
3

लगता है कि मैं यहाँ मेरी कोड प्रदान करते हैं, तो यह हो सकता है उपयोगी किसी एक ही समस्या

class PhotoField(forms.FileField, object): 

    def __init__(self, *args, **kwargs): 
     super(PhotoField, self).__init__(*args, **kwargs) 
     self.help_text = "Images over 500kb will be resized to keep under 500kb limit, which may result in some loss of quality" 

    def validate(self,image): 
     if not str(image).split('.')[-1].lower() in ["jpg","jpeg","png","gif"]: 
      raise ValidationError("File format not supported, please try again and upload a JPG/PNG/GIF file") 

    def to_python(self, image): 
     limit = 500000 
     img = Image.open(image.file) 
     width, height = img.size 
     ratio = float(width)/float(height) 
     quality = 100 
     while len(image.file.read()) > limit: 
      width -= 100 
      quality -= 10 
      height = int(width/ratio) 
      img.resize((width, height), Image.ANTIALIAS) 
      img.save(image.file.name, "JPEG", quality=quality) 
      image.file = open(image.file.name) 
      # reset the file pointer to the beginning so the while loop can read properly 
      image.file.seek(0) 
     return image 

http://james.lin.net.nz/2012/11/19/django-snippet-reduce-image-size-during-upload/

संबंधित मुद्दे