2010-12-04 17 views
13

Estoy jugando con la biblioteca PIL en Python y me pregunto cómo puedo determinar la calidad de la imagen JPG dada. Intento abrir la imagen JPG para hacer algo y guardarla de nuevo en su calidad original. Image.save déjame determinar la calidad deseada:Determinación de la calidad JPG en Python (PIL)

im.save(name, quality = x) 

pero no veo ninguna forma de extraer el original. Por ahora solo estoy adivinando e intento tener un archivo de salida del mismo tamaño como entrada haciendo una búsqueda binaria en el parámetro 'calidad' pero esto no es una solución aceptable a largo plazo :)
También traté de usar: Image.info pero la mayoría de mis imágenes no tienen ninguna información útil allí (ej: 'adobe', 'icc_profile', 'exif', 'adobe_transform')
¡Ayuda!

+1

información relevante: http://superuser.com/questions/62730/how-to-find-the-jpg-quality/91083#91083 – unutbu

+0

En general no es posible recuperar la precisa valor de calidad utilizado para comprimir un archivo JPEG porque hay varias maneras diferentes de reducir la información almacenada y el valor de calidad es solo una guía para el codificador, pero, como señala @unutbu, algunos software pueden hacer una conjetura heroica. – andrewmu

+1

Es probable que valga la pena mencionar que JPEG es un formato con pérdida, por lo que abrir y guardar una imagen degradará la calidad de la imagen, incluso si la opción "calidad" tiene el mismo valor. –

Respuesta

22

En PIL (y en su mayoría todos los softwares que utilizan/Librairies libjpeg) el ajuste de calidad es el uso para construir la tabla de cuantificación (ref.). En libjpeg, el número de calidad "escala" los valores de la tabla de muestra (de la especificación JPEG Sección K.1). En otras bibliotecas, hay diferentes tablas que se asignan a diferentes calidades (por ej .: Photoshop, cámara digital).

Por lo tanto, en otros términos, la calidad es igual a la tabla de cuantificación, por lo que es más complejo que un número.

Si desea guardar sus imágenes de modificación con la misma "calidad", solo necesita utilizar la misma tabla de cuantificación. Afortunadamente, la tabla de cuantificación está incrustada en cada JPEG. Desafortunadamente, no es posible especificar una tabla de cuantificación cuando se guarda en PIL. cjpeg, una línea de comando que viene con libjpeg, puede hacer eso.

Aquí hay algo de código bruto que guardar un archivo JPEG con una tabla de cuantificación se especifica:

from subprocess import Popen, PIPE 
from PIL import Image, ImageFilter 

proc = Popen('%s -sample 1x1 -optimize -progressive -qtables %s -outfile %s' % ('path/to/cjpeg', '/path/ta/qtable', 'out.jpg'), shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE) 
P = '6' 
if im.mode == 'L': 
    P = '5' 
stdout, stderr = proc.communicate('P%s\n%s %s\n255\n%s' % (P, im.size[0], im.size[1], im.tostring())) 

Usted tendrá que encontrar la manera de extraer la tabla de cuantificación del JPEG original.djpeg puede hacer eso (parte de libjpeg):

djpeg -verbose -verbose image.jpg > /dev/null 

Tendrá también para encontrar y establecer el muestreo. Para obtener más información sobre ese cheque here. También puede mirar en test_subsampling

ACTUALIZACIÓN

hice un tenedor PIL añadir la posibilidad de especificar las tablas de submuestreo o cuantificación o ambos al guardar JPEG. También puede especificar quality='keep' al guardar y la imagen se guardará con las mismas tablas de cuantización y submuestreo que el original (el original debe ser un JPEG). También hay algunos ajustes preestablecidos (basados ​​en Photoshop) que puede pasar a calidad al guardar. My fork.

ACTUALIZACIÓN 2

Mi código es ahora parte de Pillow 2.0. Así que acaba de hacer:

pip install Pillow 
+2

Las tablas de cuantificación también están disponibles en el atributo 'quantization' de' PIL.JpegImagePlugin.JpegImageFile' (que es el tipo que se obtiene cuando 'Image.open' es un archivo JPEG). – adw

+0

Eso es bueno saber. Entonces, lo único que falta en PIL es una forma de especificar (pasar) la tabla de cuantificación al guardar. – Etienne

+0

Dulce, especialmente que funciona con 3.3; Estoy feliz de que hayas recordado esta vieja pregunta :) –

-3

Por lo que te he entendido, esto no es posible. El formato JPEG se comprime eliminando el 75% de los datos de color o simplificando los colores. No hay forma de aumentar la calidad del color.

+0

JPEG no se "comprime eliminando el 75% de los datos de color o simplificando los colores". Hace una conversión del espacio de color a un espacio de color más eficiente (YCbCr), pero ese es solo el primer paso. – kidjan

+0

FYI: JPEG comprime comúnmente eliminando el 75% de los datos de color (submuestreo 4: 2: 0). – Arel

4

La calidad es algo que se utiliza para generar los datos que se almacenan en el archivo JPEG. Este número no está almacenado en JPEG.

Una forma en que puede determinar la calidad es tomar la celda tope de 8x8 píxeles de la imagen antes de editarla y ejecutar la fórmula de compresión JPEG solo para acercarse al original. Necesita desarrollar una función de distancia desde el resultado de eso hasta su original (diferencia de píxeles).

Seguirás haciendo una búsqueda binaria con calidad, pero es una cantidad mucho menor de trabajo.

Aquí es información sobre cómo funciona la compresión JPEG

http://www.dspguide.com/ch27/6.htm

Ésta es otra manera de un EM Preguntas

http://support.microsoft.com/kb/324790

Usted tiene que traducir de C#.

Cuestiones relacionadas