1. Mikhail Korobov
  2. psd-tools

Commits

Mikhail Korobov  committed c843d84

Python3 Pillow fork is supported; some tests for images; renames.

  • Participants
  • Parent commits 0d97d57
  • Branches default

Comments (0)

Files changed (5)

File psd_tools/cli.py

View file
 import psd_tools.reader
 import psd_tools.decoder
 from psd_tools import user_api
-from psd_tools.user_api.layers import group_layers, image_to_PIL
+from psd_tools.user_api.layers import group_layers, composite_image_to_PIL
 
 logger = logging.getLogger('psd_tools')
 logger.addHandler(logging.StreamHandler())
         with open(args['<psd_filename>'], 'rb') as f:
             res = psd_tools.reader.parse(f)
             decoded = psd_tools.decoder.parse(res)
-            im = image_to_PIL(decoded)
+            im = composite_image_to_PIL(decoded)
             im.save(args['<out_filename>'])
 
     else:

File psd_tools/user_api/__init__.py

View file
 import psd_tools.reader
 import psd_tools.decoder
 
+from .layers import group_layers
+
 def parse(filename):
     with open(filename, 'rb') as f:
-        raw_data = psd_tools.decoder.parse(
+        decoded_data = psd_tools.decoder.parse(
             psd_tools.reader.parse(f)
         )
+    return decoded_data
 
-    return raw_data
 
-

File psd_tools/user_api/layers.py

View file
                 # group begins
                 group = dict(
                     id = layer_id,
-                    _index = index,
+                    index = index,
                     name = name,
                     layers = [],
                     closed = divider.type == SectionDivider.CLOSED_FOLDER,
                 warnings.warn("invalid state")
         else:
             # layer with image
-            image = layer_to_PIL(decoded_data, index)
 
             current_group['layers'].append(dict(
                 id = layer_id,
-                _index = index,
+                index = index,
                 name = name,
-                image = image,
 
                 top = layer.top,
                 left = layer.left,
 
 def _channels_data_to_PIL(channels_data, channel_types, size):
     from PIL import Image
+    if hasattr(Image, 'frombytes'):
+        frombytes = Image.frombytes
+    else:
+        frombytes = Image.fromstring
+
     if size == (0, 0):
         return
 
             warnings.warn("Unsupported channel type (%d)" % channel_type)
             continue
         if channel.compression == Compression.RAW:
-            bands[pil_band] = Image.fromstring("L", size, channel.data, "raw", 'L')
+            bands[pil_band] = frombytes("L", size, channel.data, "raw", 'L')
         elif channel.compression == Compression.PACK_BITS:
-            bands[pil_band] = Image.fromstring("L", size, channel.data, "packbits", 'L')
+            bands[pil_band] = frombytes("L", size, channel.data, "packbits", 'L')
         elif Compression.is_known(channel.compression):
             warnings.warn("Compression method is not implemented (%s)" % channel.compression)
         else:
     return Image.merge(mode, [bands[band] for band in mode])
 
 
-def layer_to_PIL(decoded_data, layer_num):
+def layer_to_PIL(decoded_data, layer_index):
     layers = decoded_data.layer_and_mask_data.layers
-    layer = layers.layer_records[layer_num]
+    layer = layers.layer_records[layer_index]
 
-    channels_data = layers.channel_image_data[layer_num]
+    channels_data = layers.channel_image_data[layer_index]
     size = layer.width(), layer.height()
     channel_types = [info.id for info in layer.channels]
 
     return _channels_data_to_PIL(channels_data, channel_types, size)
 
-def image_to_PIL(decoded_data):
+def composite_image_to_PIL(decoded_data):
     header = decoded_data.header
     size = header.width, header.height
 

File tests/test_images.py

View file
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import, unicode_literals
+
+from psd_tools.user_api.layers import (group_layers, composite_image_to_PIL,
+                                       layer_to_PIL)
+from .utils import decode_psd
+
+def _tobytes(pil_image):
+    try:
+        return pil_image.tobytes()
+    except AttributeError:
+        return pil_image.tostring()
+
+
+def test_single_layer():
+    psd = decode_psd('1layer.psd')
+    composite_image = composite_image_to_PIL(psd)
+    layer_image = layer_to_PIL(psd, 0)
+
+    assert len(psd.layer_and_mask_data.layers.layer_records) == 1
+    assert _tobytes(layer_image) == _tobytes(composite_image)
+

File tox.ini

View file
 ; under different Python interpreters
 
 [tox]
-envlist = py26,py27,py32,py33,pypy
+envlist = py26,py27,py32,pypy
 
-[testenv]
+[base]
 deps=
     docopt >= 0.5
     pytest
     pytest-cov
     coverage
 
+[testenv]
+deps=
+    {[base]deps}
+    Pillow
+
 commands=
     py.test []
+
+[testenv:py32]
+deps=
+    {[base]deps}
+    git+https://github.com/fluggo/Pillow.git@4903496301d1a2a0cfdc0aa7fb10c4023e75d8af#egg=Pillow
+
+[testenv:py33]
+deps=
+    {[base]deps}
+    git+https://github.com/fluggo/Pillow.git@4903496301d1a2a0cfdc0aa7fb10c4023e75d8af#egg=Pillow