PMXBOT Log file Viewer

Help | Karma | Search:

#pil logs for Tuesday the 22nd of October, 2013

(Back to #pil overview) (Back to channel listing) (Animate logs)
[15:41:23] <Heiber> Hello
[15:41:39] <Heiber> I am having a problem with Pillow
[15:42:00] <Heiber> I have an image in a StringIO tiff uncompressed 300 dpi.
[15:42:34] <Heiber> I convert it to bitonal then I save it compressed group3 and image changes to 96dpi
[15:42:46] <Heiber> If I put dpi=(300,300) an error ocurred
[15:42:54] <wiredfool> right.
[15:43:31] <Heiber> wred
[15:43:33] <Heiber> hello
[15:43:41] <Heiber> All worked yesterday
[15:43:45] <Heiber> except that
[15:44:04] <Heiber> img.save("c:/Scanner/prueba.tiff", dpi=(300,300))
[15:44:05] <wiredfool> basically, tuple items in the imagefiledirectory aren't handled well, since there's a line that's assuming a one item tuple
[15:44:28] <Heiber> this is the tuple
[15:44:29] <Heiber> [(256, (4200,)), (257, (2552,)), (259, (3,)), (262, (1,)), (296, (2,)), (273, (0,)), (278, (2552,)), (279, (1339800,)), (282, (300, 1)), (283, (300, 1))]
[15:44:39] <Heiber> I think problem are lastest two
[15:44:44] <wiredfool> try.. oh hell. someone put 'x resolution' in as an encoder info thing
[15:45:08] <Heiber> only happens when image is bitonal
[15:45:16] <Heiber> but I need it in 300 dpi
[15:45:41] <wiredfool> try: atts={'x resolution':300, 'y resolution': 300}; img.save('filename.tiff', **atts)
[15:46:31] <wiredfool> or maybe not, the get converted to rationals
[15:46:37] <Heiber> dpi = im.encoderinfo.get("dpi")
[15:46:37] <Heiber> print (im.encoderinfo)
[15:46:37] <Heiber> if dpi:
[15:46:37] <Heiber> print (dpi)
[15:46:37] <Heiber> ifd[RESOLUTION_UNIT] = 2
[15:46:39] <Heiber> ifd[X_RESOLUTION] = _cvt_res(dpi[0])
[15:46:41] <Heiber> ifd[Y_RESOLUTION] = _cvt_res(dpi[1])
[15:47:08] <wiredfool> nm, they both get converted to rationals and are goign to fail on that atts line.
[15:48:19] <Heiber> maybe some change on tiffimageplugin?
[15:48:59] <Heiber> it should be (282, (300,)) ?
[15:49:21] <wiredfool> ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]''''''''''''''''''']]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
[15:49:31] <Heiber> :O
[15:49:34] <wiredfool> sorry, cat on the keyboard
[15:49:48] <wiredfool> persistent little thing
[15:50:01] <Heiber> jejeje
[15:50:02] <wiredfool> no, so, resolution is a rational, which is a list of two items.
[15:50:38] <Heiber> maybe if harcode it after loop of tuples?
[15:51:12] <wiredfool> It's time to kill the offending line for good. I think I've got a solution.
[15:51:16] <wiredfool> #atts = dict([(k,v) for (k,(v,)) in ifd.items() if k not in blocklist])
[15:51:16] <wiredfool> atts={}
[15:51:16] <wiredfool> try:
[15:51:16] <wiredfool> # pull in more bits from the original file, e.g x,y resolution
[15:51:16] <wiredfool> # so that we can save(load('')) == original file.
[15:51:17] <wiredfool> for k,v in itertools.chain(ifd.items(), im.ifd.items()):
[15:51:35] <wiredfool> that first comment line is 1014 in TiffImagePlugin.
[15:51:42] <Heiber> let me check
[15:52:03] <Heiber> comment on atts =...
[15:52:23] <Heiber> commented
[15:52:39] <wiredfool> make atts a new dict, then we'll just fill using both ifds, using itertools.chain
[15:52:54] <wiredfool> so add the atts={} line, and change the for line
[15:54:07] <Heiber> done
[15:54:18] <Heiber> some another change?
[15:55:47] <wiredfool> for k,v in itertools.chain(ifd.items(), im.ifd.items()):
[15:55:55] <wiredfool> from for k,v in im.ifd.items():
[15:57:00] <Heiber> sorry I dont understand those changes
[15:57:18] <Heiber> blocklist = [STRIPOFFSETS, STRIPBYTECOUNTS, ROWSPERSTRIP, ICCPROFILE] # ICC Profile crashes.
[15:57:18] <Heiber> #atts = dict([(k,v) for (k,(v,)) in ifd.items() if k not in blocklist])
[15:57:18] <Heiber> atts = {}
[15:57:18] <Heiber> try:
[15:57:18] <Heiber> # pull in more bits from the original file, e.g x,y resolution
[15:57:19] <Heiber> # so that we can save(load('')) == original file.
[15:57:21] <Heiber> #for k,v in im.ifd.items():
[15:57:23] <Heiber> for k,v in itertools.chain(ifd.items(),im.ifd.items()):
[15:57:25] <Heiber> if k not in atts and k not in blocklist:
[16:00:27] <wiredfool> that looks right
[16:00:59] <Heiber> TIFFWriteScanline: Must set "ImageWidth" before writing data.
[16:00:59] <Heiber> Traceback (most recent call last):
[16:01:00] <Heiber> File "C:/Users/Heiber Bustos/PycharmProjects/scanner/scannerGui.py", line 211, in run
[16:01:00] <Heiber> self.barcodeImagen(self.imagen_a_procesar)
[16:01:00] <Heiber> File "C:/Users/Heiber Bustos/PycharmProjects/scanner/scannerGui.py", line 267, in barcodeImagen
[16:01:00] <Heiber> imagen_tiff_bw.save("c:/Scanner/" + symbol.data + ".tiff", 'TIFF', dpi=(300,300))
[16:01:02] <Heiber> File "C:\Python27\lib\site-packages\PIL\Image.py", line 1453, in save
[16:01:04] <Heiber> save_handler(self, fp, filename)
[16:01:06] <Heiber> File "C:\Python27\lib\site-packages\PIL\TiffImagePlugin.py", line 1056, in _save
[16:01:10] <Heiber> raise IOError("encoder error %d when writing image file" % s)
[16:01:12] <Heiber> IOError: encoder error -2 when writing image file
[16:01:21] <wiredfool> ok.
[16:07:25] <Heiber> it neves enter the loop
[16:07:30] <Heiber> atts is not filled
[16:08:49] <wiredfool> I'm currently juggling three branches with stiff that relates to libtiff and tags.
[16:09:05] <wiredfool> [ython 3 is failing with strings
[16:09:16] <Heiber> Python 2.7 here
[16:09:21] <wiredfool> one branch is arbitrary tags
[16:09:32] <wiredfool> and one branch is failing with endian issues
[16:09:38] <wiredfool> and then there's yours.
[16:10:41] <wiredfool> Right, I've got the imagewidth one now.
[16:10:45] <wiredfool> in one place
[16:11:29] <Heiber> oops
[16:13:09] <wiredfool> there's going to be one hell of a merge when this is done
[16:15:00] <wiredfool> ah. I understand now
[16:15:18] <Heiber> :)
[16:15:24] <Heiber> that's sounds good
[16:16:11] <Heiber> maybe to solve this I can put dpi atts fixed?
[16:17:52] <Heiber> atts[282] = 300 or something like that?
[16:19:55] <Heiber> when im.mode == '1' and compression thing is enabled...
[16:21:19] <Heiber> I dont understand why it not preserve image original DPI
[16:22:18] <wiredfool> Im.convert doesn't pull in the original imagefiledirectory
[16:22:31] <wiredfool> you know, what you could do is:
[16:22:41] <wiredfool> bw = im.convert('1')
[16:22:49] <wiredfool> bw.ifd = im.ifd
[16:22:59] <wiredfool> but -- that's going to pull in other things like bytes per sample
[16:23:11] <Heiber> sure, not good that
[16:23:31] <Heiber> dpi is the same as X RESOLUTION and Y RESOLUTION?
[16:23:35] <wiredfool> this is the patch, should fix the bit where it's not getting into the loop
[16:23:44] <wiredfool> if github would come up
[16:24:30] <wiredfool> https://github.com/wiredfool/Pillow/commit/32e2f97b215985933ef3aada4451d03f478f0be4
[16:24:42] <wiredfool> the first part anyway, the print is an accident
[16:27:38] <Heiber> let me try
[16:28:48] <Heiber> oops dpi still 96dpi
[16:29:23] <Heiber> not changed
[16:29:29] <Heiber> but not error now
[16:29:35] <Heiber> just dpi are not changed
[16:32:37] <wiredfool> it should default to what's passed in with the save, if not, fall back to the original
[16:33:33] <Heiber> original is 300
[16:33:47] <Heiber> mmm to libtiff how I pass dpi information in atts?
[16:34:55] <wiredfool> imagen_tiff_bw.save("c:/Scanner/" + symbol.data + ".tiff", 'TIFF', dpi=(300,300))
[16:34:59] <wiredfool> that should be doing it
[16:36:00] <Heiber> not working... let me show
[16:39:01] <Heiber> http://picpaste.com/96dpi-9J5Tf3vc.png
[16:41:38] <wiredfool> if you set Image.DEBUG, what do the atts and the ifd look like?
[16:44:20] <Heiber> 0:((1712, 269), (1712, 271), (1974, 272), (1712, 273), (1974, 274), (1712, 275), (1974, 276), (1712, 277), (1974, 278), (1712, 279), (1974, 280), (1712, 281), (1974, 282), (1712, 283), (1974, 284), (1712, 285), (1974, 286), (1712, 287), (1974, 288), (1712, 289), (1974, 290), (1712, 291), (1974, 292), (1712, 293), (1974, 294), (1712, 295), (1974, 296), (1712, 297), (1974, 298), (1712, 299), (1974, 300), (1712, 301), (1974, 302), (1712, 303), (1974, 304), (1712
[16:44:20] <Heiber> , 305), (1974, 306), (1712, 307), (1974, 308), (1712, 309), (1974, 310), (1712, 311), (1712, 313), (1974, 314), (1712, 315), (1974, 316), (1712, 317), (1712, 319), (1712, 321), (1974, 322), (1712, 323), (1974, 324), (1712, 325), (1974, 326), (1712, 327), (1974, 328), (1712, 329), (1974, 330), (1712, 331), (1974, 332), (1712, 333), (1974, 334), (1712, 335), (1974, 336), (1712, 337), (1974, 338), (1712, 339), (1974, 340), (1712, 341), (1974, 342), (1712, 343),
[16:44:21] <Heiber> (1974, 344), (1712, 345), (1974, 346), (1712, 347), (1974, 348), (1974, 350), (1712, 351), (234, 2778), (236, 2778), (237, 2450), (238, 2778), (239, 2451), (240, 2778), (241, 2450), (242, 2778), (243, 2450), (244, 2778), (245, 2450), (246, 2778), (247, 2451), (248, 2778), (249, 2451), (250, 2778), (251, 2451), (252, 2778), (253, 2451), (254, 2778), (255, 2450), (256, 2778), (257, 2451), (258, 2778), (259, 2451), (260, 2778), (261, 2451), (262, 2778), (263, 24
[16:44:26] <Heiber> 50), (264, 2778), (265, 2450), (266, 2778), (267, 2450), (268, 2778), (269, 2451), (270, 2778), (271, 2450), (272, 2778), (273, 2451), (274, 2778), (275, 2451), (276, 2778), (277, 2450), (278, 2778), (279, 2450), (280, 2778), (281, 2450), (282, 2778), (283, 2450), (284, 2778), (285, 2450), (286, 2778), (288, 2778), (289, 2450), (290, 2778), (292, 2778), (293, 2450), (294, 2778), (295, 2450), (296, 2778), (297, 2450), (298, 2778), (299, 2450), (300, 2778), (30
[16:44:31] <Heiber> 1, 2450), (302, 2778), (303, 2450), (304, 2778), (305, 2450), (306, 2777), (307, 2450), (308, 2777), (309, 2450), (310, 2777), (311, 2450), (312, 2778), (313, 2450), (314, 2777), (315, 2450), (316
[16:44:42] <Heiber> Saving using libtiff encoder
[16:44:42] <Heiber> [(256, (4200,)), (257, (2552,)), (259, (3,)), (262, (1,)), (296, (2,)), (273, (0,)), (278, (2552,)), (279, (1339800,)), (282, (300, 1)), (283, (300, 1))]
[16:44:43] <Heiber> {'dpi': (300, 300)}
[16:44:43] <Heiber> ()
[16:44:45] <Heiber> 1
[16:44:47] <Heiber> group3
[16:44:49] <Heiber> ATTRS:
[16:44:51] <Heiber> {256: 4200, 257: 2552, 259: 3, 262: 1, 296: 2}
[16:44:53] <Heiber> ('1', 'group3', 4, 'c:/Scanner/00002405.tiff', {256: 4200, 257: 2552, 259: 3, 262: 1, 296: 2})
[16:45:07] <Heiber> I put some additionals prints
[16:45:14] <Heiber> lastes is variable a
[16:45:29] <Heiber> yo can see there variable atts too
[16:45:46] <Heiber> after ATTRS:
[16:46:11] <Heiber> yo can see too that dpi is set
[16:46:41] <wiredfool> right.
[16:47:02] <Heiber> and () es im.encoderconfig that is empty
[16:47:13] <Heiber> 1 is im.mode
[16:47:23] <Heiber> group3 is variable compression
[16:52:11] <wiredfool> tuple lists of rationals, ok. single rational tuple, doesn't copy
[16:53:45] <Heiber> I can see that
[16:54:05] <wiredfool> if type(v) == tuple and len(v) == 2:
[16:54:05] <wiredfool> # one rational tuple
[16:54:05] <wiredfool> # flatten to float, following tiffcp.c->cpTag->TIFF_RATIONAL
[16:54:05] <wiredfool> atts[k] = float(v[0])/float(v[1])
[16:54:05] <wiredfool> continue
[16:58:30] <Heiber> worked!
[16:58:38] <Heiber> I have 300dpi in image propertioes
[16:59:16] <Heiber> you have to appy that patch
[17:03:03] <wiredfool> Yep.
[17:05:07] <wiredfool> all tests pass, py27, 3.2
[17:06:33] <Heiber> good
[17:06:39] <Heiber> only thing is:
[17:07:02] <Heiber> I have an image saved on 300 dpi, same resolution and bitonal, it is 200Kb
[17:07:10] <Heiber> but same image saved with pillow is 95Kb
[17:07:13] <Heiber> same compression
[17:08:15] <wiredfool> are the bits the same?
[17:08:24] <wiredfool> when decompressed?
[17:08:35] <Heiber> how can i check that?
[17:09:33] <wiredfool> https://github.com/python-imaging/Pillow/blob/master/Tests/tester.py#L168
[17:10:53] <Heiber> so I open two images and compare ?
[17:12:01] <wiredfool> yep.
[17:12:12] <wiredfool> if it's lossless compression, then the bits will be the same
[17:12:33] <wiredfool> then you know that it's either in the metadata, or the compression method is slightly different
[17:12:46] <wiredfool> (iirc, there are two g3 methods, one is 1d, one is 2d)
[17:14:06] <Heiber> size and mode are the same
[17:15:18] <Heiber> well I rotated the image...
[17:17:01] <wiredfool> ah
[17:17:11] <wiredfool> well then...
[17:19:44] <Heiber> I open both with gimp
[17:19:47] <Heiber> same pixels
[17:19:50] <Heiber> same size
[17:20:03] <Heiber> same resolution
[17:20:08] <Heiber> same print size
[17:20:32] <Heiber> only difference is that one has UNDO STEPS (I dont know what is that)
[17:21:50] <wiredfool> ah
[17:21:59] <wiredfool> I think you're good then
[17:23:01] <Heiber> print im1.tobytes() != im2.tobytes()
[17:23:01] <Heiber> False
[17:23:24] <wiredfool> oh, thought that was the pixels
[17:23:32] <wiredfool> how different are they?
[17:23:41] <wiredfool> when you look?
[17:23:55] <Heiber> check I am checkinf if they are different
[17:23:58] <Heiber> and return FALSE
[17:24:28] <Heiber> print im1.tobytes() == im2.tobytes()
[17:24:28] <Heiber> True
[17:25:23] <wiredfool> ph.
[17:25:30] <wiredfool> oh. that's better
[17:25:36] <Heiber> yes
[17:25:53] <Heiber> maybe as you said is a different g3 compressoin method