Example #1
0
"""
from __future__ import absolute_import, unicode_literals
import attr
from collections import OrderedDict
import codecs
import io
import logging
import re
from enum import Enum
from psd_tools.psd.base import (BooleanElement, DictElement, IntegerElement,
                                ListElement, NumericElement, ValueElement)
from psd_tools.utils import new_registry, trimmed_repr, write_bytes

logger = logging.getLogger(__name__)

TOKEN_CLASSES, register = new_registry()


def compile_re(pattern):
    return re.compile(pattern.encode('macroman'), re.S)


class EngineToken(Enum):
    ARRAY_END = compile_re(r'^\]$')
    ARRAY_START = compile_re(r'^\[$')
    BOOLEAN = compile_re(r'^(true|false)$')
    DICT_END = compile_re(r'^>>(\x00)*$')  # Buggy one?
    DICT_START = compile_re(r'^<<$')
    NOOP = compile_re(r'^$')
    NUMBER = compile_re(r'^-?\d+$')
    NUMBER_WITH_DECIMAL = compile_re(r'^-?\d*\.\d+$')
Example #2
0
from psd_tools.psd.base import (
    BaseElement, EmptyElement, ListElement, ShortIntegerElement,
)
from psd_tools.psd.color import Color
from psd_tools.psd.descriptor import DescriptorBlock, DescriptorBlock2
from psd_tools.validators import in_
from psd_tools.utils import (
    read_fmt, write_fmt, read_length_block, write_length_block, is_readable,
    write_bytes, read_unicode_string, write_unicode_string, write_padding,
    read_pascal_string, write_pascal_string, trimmed_repr, new_registry
)

logger = logging.getLogger(__name__)


ADJUSTMENT_TYPES, register = new_registry()

ADJUSTMENT_TYPES.update({
    TaggedBlockID.BLACK_AND_WHITE: DescriptorBlock,
    TaggedBlockID.GRADIENT_FILL_SETTING: DescriptorBlock,
    TaggedBlockID.INVERT: EmptyElement,
    TaggedBlockID.PATTERN_FILL_SETTING: DescriptorBlock,
    TaggedBlockID.POSTERIZE: ShortIntegerElement,
    TaggedBlockID.SOLID_COLOR_SHEET_SETTING: DescriptorBlock,
    TaggedBlockID.THRESHOLD: ShortIntegerElement,
    TaggedBlockID.VIBRANCE: DescriptorBlock,
})


@register(TaggedBlockID.BRIGHTNESS_AND_CONTRAST)
@attr.s(slots=True)
Example #3
0
from psd_tools.validators import in_
from psd_tools.utils import (
    read_fmt,
    write_fmt,
    read_unicode_string,
    write_unicode_string,
    write_bytes,
    read_length_block,
    write_length_block,
    write_padding,
    new_registry,
)

logger = logging.getLogger(__name__)

TYPES, register = new_registry(attribute='ostype')

_TERMS = set(item.value for kls in (Klass, Enum, Event, Form, Key, Type, Unit)
             for item in kls)


def read_length_and_key(fp):
    """
    Helper to read descriptor key.
    """
    length = read_fmt('I', fp)[0]
    key = fp.read(length or 4)
    if length == 0 and key not in _TERMS:
        logger.debug('Unknown term: %r' % (key))
        _TERMS.add(key)
    return key
Example #4
0
from psd_tools.psd.engine_data import EngineData, EngineData2
from psd_tools.psd.filter_effects import FilterEffects
from psd_tools.psd.linked_layer import LinkedLayers
from psd_tools.psd.patterns import Patterns
from psd_tools.psd.vector import (VectorMaskSetting,
                                  VectorStrokeContentSetting)
from psd_tools.validators import in_
from psd_tools.utils import (read_fmt, write_fmt, read_length_block,
                             write_length_block, is_readable, write_bytes,
                             read_unicode_string, write_unicode_string,
                             write_padding, read_pascal_string,
                             write_pascal_string, trimmed_repr, new_registry)

logger = logging.getLogger(__name__)

TYPES, register = new_registry()

TYPES.update(ADJUSTMENT_TYPES)
TYPES.update({
    TaggedBlockID.ANIMATION_EFFECTS:
    DescriptorBlock,
    TaggedBlockID.ARTBOARD_DATA1:
    DescriptorBlock,
    TaggedBlockID.ARTBOARD_DATA2:
    DescriptorBlock,
    TaggedBlockID.ARTBOARD_DATA3:
    DescriptorBlock,
    TaggedBlockID.BLEND_CLIPPING_ELEMENTS:
    ByteElement,
    TaggedBlockID.BLEND_FILL_OPACITY:
    ByteElement,
Example #5
0
"""
from __future__ import absolute_import, unicode_literals
import attr
import logging

from psd_tools.psd.base import BaseElement, ListElement, ValueElement
from psd_tools.constants import PathResourceID
from psd_tools.psd.descriptor import Descriptor
from psd_tools.utils import (read_fmt, write_fmt, read_length_block,
                             write_length_block, is_readable, write_bytes,
                             write_padding, new_registry)
from psd_tools.validators import in_

logger = logging.getLogger(__name__)

TYPES, register = new_registry(attribute='selector')  # Path item types.


def decode_fixed_point(numbers):
    return tuple(float(x) / 0x01000000 for x in numbers)


def encode_fixed_point(numbers):
    return tuple(int(x * 0x01000000) for x in numbers)


@attr.s(repr=False, slots=True)
class Path(ListElement):
    """
    List-like Path structure. Elements are either PathFillRule,
    InitialFillRule, ClipboardRecord, ClosedPath, or OpenPath.
Example #6
0
    if layer.kind == 'brightnesscontrast':
        print(layer.brightness)

    if layer.kind == 'gradient-fill':
        print(layer.gradient_kind)
"""
from __future__ import absolute_import
import logging

from psd_tools.api.layers import AdjustmentLayer, FillLayer
from psd_tools.constants import TaggedBlockID
from psd_tools.utils import new_registry

logger = logging.getLogger(__name__)

TYPES, register = new_registry(attribute='_KEY')


@register(TaggedBlockID.SOLID_COLOR_SHEET_SETTING)
class SolidColorFill(FillLayer):
    """Solid color fill."""
    @property
    def data(self):
        """Color in Descriptor(RGB)."""
        return self._data.get(b'Clr ')


@register(TaggedBlockID.PATTERN_FILL_SETTING)
class PatternFill(FillLayer):
    """Pattern fill."""
    @property
Example #7
0
Blending module.

Check Blending_ section of W3C recommendation for blending mode definitions.

.. _Blending: https://www.w3.org/TR/compositing/#blending
"""
from __future__ import absolute_import, unicode_literals
import logging

from psd_tools.utils import new_registry
from psd_tools.constants import BlendMode
from psd_tools.terminology import Enum

logger = logging.getLogger(__name__)

BLEND_FUNCTIONS, register = new_registry()


def blend(backdrop, image, offset, mode=None):
    from PIL import Image

    # Align the canvas size.
    if offset[0] < 0:
        if image.width <= -offset[0]:
            return backdrop
        image = image.crop((-offset[0], 0, image.width, image.height))
        offset = (0, offset[1])

    if offset[1] < 0:
        if image.height <= -offset[1]:
            return backdrop