La compressione JPEG non è prevedibile in anticipo. Il metodo che hai descritto, comprimere & misurare & riprovare, è l'unico modo che conosco.
È possibile provare a comprimere un numero di immagini tipiche con impostazioni di qualità diverse per avere un'idea del punto di partenza ottimale, oltre a un modo per indovinare in che modo le modifiche all'impostazione influiscono sulle dimensioni. Ciò ti porterà a zero sulla dimensione ottimale senza troppe iterazioni.
È anche possibile passare un oggetto di tipo file alla funzione save
che non si preoccupa di scrivere sul disco, conta solo i byte. Una volta determinate le migliori impostazioni, puoi salvarle nuovamente in un file reale.
Modifica: ecco un'implementazione di un oggetto file di conteggio di byte adatto. Basta controllare size
dopo il salvataggio.
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)
Edit 2: Ecco una ricerca binaria utilizzando il sopra per ottenere l'ottimale quality
nel minor numero di tentativi.
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
fonte
2012-11-15 23:08:59
Un modo migliore per farlo è quello di ricercare la qualità in binario. Quindi inizia con il 50% di qualità, quindi controlla le dimensioni, se è troppo piccolo, prova il 75%, altrimenti prova il 25%, ecc. Ti avvicinerai il più possibile a 500 KB, potresti inoltre impostare alcuni parametri aggiuntivi, ad es. qualità minima o tolleranza dimensionale. Dovresti essere in grado di azzerare il livello di compressione corretto in al massimo 7 iterazioni. –