<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:Courier New,courier,monaco,monospace,sans-serif;font-size:10pt"><div>Here's some code that does the trick.<br><br>It returns a tuple:<br>(coefficient, (luminance_coefficient,luminance_error), (chrominance_coefficient,chrominance_error))<br><br>Note:<br>- The 2nd and 3rd returned items are only useful if you're interested in the error (sometimes the error is 0 if the program used a JPEG table that is the same as the one used by PIL).<br>- Fredrik: You can freely use the code and embed it in PIL if you're satisfied with its quality<br><br>Code:<br>def get_jpeg_quantization_tables(f):<br> """Returns the JPEG quantization tables of a filename or file descriptor"""<br> from functools import partial<br> import Image<br> import numpy as N<br> fd =
Image.open(f)<br> if fd.format == 'BMP':<br> return N.ones((8,8)),N.ones((8,8))<br> q = fd.quantization<br> ql,qc = map(partial(N.array,dtype='uint8'),(q.get(0,N.zeros(64)),q.get(1,N.zeros(64))))<br> # Now reorder the JPEG quantification coefficients as 8x8 matrices<br> jpeg_natural_order = N.array([ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12,<br> 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35,
42,<br> 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52,<br> 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63])<br> rql = N.zeros(64,'f')<br> rqc = N.zeros(64,'f')<br> for x,y in N.ndenumerate(jpeg_natural_order):<br> rql[y] = ql[x]<br> rqc[y] = qc[x]<br> return rql.reshape(8,8),rqc.reshape(8,8) # Luminance/Chrominance<br><br>def
guess_jpeg_quality(f,ctables=[]):<br> from StringIO import StringIO<br> import numpy as N<br> import Image<br> # Compute the tables for quality = 1..100 by saving fakes files in memory<br> if not ctables:<br> tables = N.zeros((100,2,8,8),'f')<br> for x in xrange(100):<br> fd = StringIO()<br> Image.new('RGB',(64,64)).save(fd,"jpeg",quality=1+x)<br> fd.seek(0)<br> ql,qc = get_jpeg_quantization_tables(fd)<br> tables[x][0] =
ql<br> tables[x][1] = qc<br> ctables.append(tables)<br> else:<br> tables = ctables[0]<br> # Use a weighting matrix w to put more emphasis on the comparison of lower DCT harmonics<br> w = 1./N.outer(1+N.arange(8)/7.,1+N.arange(8)/7.)<br> ql,qc = get_jpeg_quantization_tables(f)<br> # Compute errors on Luminance and Chrominance tables<br> errsl,errsc = [],[]<br> for x in xrange(100):<br> errsl.append((N.square((ql-tables[x][0])*w).mean(),x))<br> errsc.append((N.square((qc-tables[x][1])*w).mean(),x))<br> # Select minimal error coefficients<br>
lmin = min(errsl)<br> cmin = min(errsc)<br> # Weight coefficients average (more emphasis put on luminance since it affects most visual perception)<br> q = int(round(lmin[1]*.8 + cmin[1]*.2))<br> return q,lmin,cmin<br><br><br></div><div style="font-family: Courier New,courier,monaco,monospace,sans-serif; font-size: 10pt;"><br><div style="font-family: arial,helvetica,sans-serif; font-size: 10pt;"><font face="Tahoma" size="2"><hr size="1"><b><span style="font-weight: bold;">From:</span></b> Fredrik Lundh <fredrik@pythonware.com><br><b><span style="font-weight: bold;">To:</span></b> qiaohl <qiaohl@ucweb.com><br><b><span style="font-weight: bold;">Cc:</span></b> image-sig <image-sig@python.org><br><b><span style="font-weight: bold;">Sent:</span></b> Monday, September 28, 2009 5:43:00 AM<br><b><span style="font-weight: bold;">Subject:</span></b> Re: [Image-SIG] How to
get quality of picture<br></font><br>The quality setting is used to create a quantization table which is<br>then used by the compression algorithm. There's no pre-defined<br>mapping between quality and the contents of the quantization table for<br>JPEG (different implementations do different things), but some<br>applications attempt to guess by comparing the quantization tables in<br>the file with known mapping algorithms. I'm not aware of any such<br>code for Python.<br><br>If you want to tinker with this, you can access the quantization table<br>of an opened JPEG file via the "quantization" attribute.<br><br></F><br><br>On Mon, Sep 28, 2009 at 9:08 AM, qiaohl <<a ymailto="mailto:qiaohl@ucweb.com" href="mailto:qiaohl@ucweb.com">qiaohl@ucweb.com</a>> wrote:<br>> Hi,all<br>> Is there any function in PIL to get the value of JPEG quality(1-100)? I<br>> know there are functions to set this value, But I
found no function to get<br>> this value of an existing JPEG file.<br>><br>> Thanks!<br>><br>><br>> 2009-09-28<br>> ________________________________<br>> qiaohl<br>> _______________________________________________<br>> Image-SIG maillist - <a ymailto="mailto:Image-SIG@python.org" href="mailto:Image-SIG@python.org">Image-SIG@python.org</a><br>> <a href="http://mail.python.org/mailman/listinfo/image-sig" target="_blank">http://mail.python.org/mailman/listinfo/image-sig</a><br>><br>><br>_______________________________________________<br>Image-SIG maillist - <a ymailto="mailto:Image-SIG@python.org" href="mailto:Image-SIG@python.org">Image-SIG@python.org</a><br><a href="http://mail.python.org/mailman/listinfo/image-sig" target="_blank">http://mail.python.org/mailman/listinfo/image-sig</a><br></div></div></div><br>
</body></html>