Как работать с ресурсами изображений PSD в Python
Загруженный PsdImage предоставляет свои блоки ресурсов изображений — записи в стиле метаданных, такие как сетки, направляющие и полезные нагрузки ICC-профиля — через два только для чтения представления, а также отдельную сводку для индексированных палитр цветов.
Пошаговое руководство
Шаг 1: Установите пакет
git clone https://github.com/aspose-psd-foss/Aspose.PSD-FOSS-for-Python.git
cd Aspose.PSD-FOSS-for-Python
# No packaging manifest is published yet -- run from this folder,
# or add it to PYTHONPATH:
export PYTHONPATH=$PWD:$PYTHONPATHШаг 2: Импортируйте необходимые классы
from aspose_psd_foss.psdimage import PsdImage
from aspose_psd_foss.resources.imageresourceids import ImageResourceIdsШаг 3: Проверьте и подсчитайте ресурсы изображений
image = PsdImage.load("input.psd")
print(f"Has image resources: {image.has_image_resources}")
print(f"Resource count: {image.resource_count}")Шаг 4: Список блоков ресурсов через image_resources
PsdImage.image_resources возвращает PreservedResourceBlock для каждого ресурса, содержащий необработанный идентификатор ресурса, имя и размер в байтах:
for block in image.image_resources:
print(f"ID: {block.id}, name: {block.name!r}, size: {block.size} bytes")Определите конкретный ресурс, сравнив block.id с известными константами в ImageResourceIds:
for block in image.image_resources:
if block.id == ImageResourceIds.ICC_PROFILE:
print(f"Found an ICC profile resource ({block.data_size} bytes)")Парсер ресурсов в этой сборке FOSS не декодирует идентификаторы ресурсов в семантические свойства сам по себе — сравнение block.id с ImageResourceIds вручную является поддерживаемым способом распознать конкретный ресурс.
Шаг 5: Список сводок ресурсов через resources
PsdImage.resources возвращает отдельную PsdResourceInfo сводку для каждого ресурса, включая классификацию kind:
for info in image.resources:
print(f"ID: {info.resource_id}, kind: {info.kind}, data length: {info.data_length}")В этой сборке FOSS kind всегда PsdResourceKind.UNKNOWN — семантическая классификация конкретных типов ресурсов (глобальный угол, ICC-профиль) не реализована, поэтому рассматривайте kind только как информационную и полагайтесь на resource_id (Шаг4) для распознавания конкретного ресурса.
Шаг 6: Чтение индексированной цветовой палитры
Если цветовые данные документа основаны на палитре, PsdImage.indexed_palette возвращает её записи:
palette = image.indexed_palette
if palette is not None:
print(f"Palette entries: {len(palette.entries)}")Распространённые проблемы и решения
image.indexed_palette is None. Тип цветовых данных документа не INDEXED_PALETTE — только документы с индексированными цветами содержат палитру.
Setting image.image_resources raises NotSupportedException. Геттер работает для перечисления ресурсов, но сеттер не поддерживается в этой FOSS-сборке.
Calling block.save() на PreservedResourceBlock raises NotImplementedError. Сохранение отдельных блоков ресурсов напрямую не поддерживается — ресурсы автоматически проходят сквозной проход, когда вы вызываете image.save() на всём документе.
has_icc_profile, is_icc_profile_untagged, и global_angle никогда не меняются. Эти три PsdImage свойства являются фиксированными заполнительными значениями в этой FOSS-сборке (has_icc_profile всегда False, is_icc_profile_untagged всегда None, global_angle всегда 0) независимо от фактического содержимого загруженного документа — парсер ресурсов этой сборки не восстанавливает семантические значения, специфичные для ID. Используйте сравнение из Шага4 block.id сравнение с ImageResourceIds если вам нужно самостоятельно обнаружить эти ресурсы.
Часто задаваемые вопросы
В чём разница между image_resources и resources?
Оба перечисляют одинаковые базовые блоки ресурсов, но как разные типы объектов: image_resources возвращает объекты PreservedResourceBlock (raw ID/name/size, used for round-tripping), в то время как resources возвращает сводки PsdResourceInfo (добавляет классификацию kind, в настоящее время всегда UNKNOWN).
Можно ли изменить или удалить ресурс изображения?
Нет — сеттер image_resources генерирует NotSupportedException, а PreservedResourceBlock.save() генерирует NotImplementedError при прямом вызове. Ресурсы доступны только для чтения в этой FOSS-сборке.