""" 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+$')
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)
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
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,
""" 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.
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
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