Различайте векторные и растровые изображения с помощью python-pptx

#python #bitmap #powerpoint #vector-graphics #python-pptx

Вопрос:

У меня есть файл PowerPoint (.pptx), который включает в себя как векторную, так и растровую графику.

Я пытаюсь автоматически идентифицировать и пометить растровые изображения толстой красной линией границы. Векторные изображения не должны быть помечены.

Я написал следующий сценарий, чтобы поместить красную рамку вокруг изображений:

 from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.util import Pt

prs = Presentation("test.pptx")

for slide_id, slide in enumerate(prs.slides):
    slide_number = slide_id   1
    for shape_id, shape in enumerate(slide.shapes):
        # print(slide_number, shape.shape_type)
        if shape.shape_type == 13:  # if shape is an image
            # print(slide_number, shape.image.content_type)
            if shape.image.content_type == "image/png":
                line = shape.line
                line.color.rgb = RGBColor(255, 0, 0)
                line.width = Pt(3.0)
            if shape.image.content_type == "image/jpeg":
                line = shape.line
                line.color.rgb = RGBColor(255, 0, 0)
                line.width = Pt(3.0)

prs.save("out.pptx")
 

Проблема: также векторные изображения отмечены красной рамкой, потому что их shape.image.content_type == «изображение/png».

Как я могу отфильтровать векторные изображения?

Комментарии:

1. PNG не является векторным форматом. Преобразуются ли они с помощью PowerPoint?

2. Векторное изображение было импортировано в колоду .pptx из векторного формата (SVG), а также может быть снова экспортировано из колоды .pptx в векторный формат (SVG). Экспортированное изображение является фактическим векторным форматом: его можно масштабировать до очень большого формата без отображения пикселизации. Из-за этого я предполагаю, что PowerPoint сохраняет информацию о векторе/пути, но потенциально также отображает ее в формате PNG.

3. Имеет смысл, что PowerPoint сохранит PNG, потому что более ранние версии PowerPoint не могут отображать SVG, и для этого требуется версия с наименьшим общим знаменателем, чтобы гарантировать, что презентация может быть загружена всеми поддерживаемыми версиями. Если вы проверите XML на наличие этой формы, print(shape._element.xml) вы можете обнаружить некоторые подсказки. Я ожидаю, что он хранит как исходный SVG, так и формат PNG, отображаемый в текущих размерах.

4. Спасибо @scanny , shape._element.xml действительно содержал ссылки на «svg»! Я опубликую свое решение ниже.

5. Связано, и я не уверен, что на 100% был дан ответ выше, может ли python-pptx напрямую импортировать SVG? Сегодня md2pptx преобразуется в PNG под обложками и устанавливает размеры при этом. Очевидно, что не проводить преобразование было бы лучше.

Ответ №1:

shape._element.xml содержит ссылки на «svg», которые можно использовать для различения векторных и растровых изображений.

Полный рабочий пример:

 from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.util import Pt
from pptx.enum.dml import MSO_LINE


def mark_shape(shape):
    line = shape.line
    line.color.rgb = RGBColor(255, 0, 0)
    line.width = Pt(3.0)
    line.dash_style = MSO_LINE.DASH
    return


def check_bitmap(shape):
    if shape.shape_type == 13:  # if shape is an image
        if shape.image.content_type == "image/png":
            if "asvg" not in shape._element.xml:
                return True
        if shape.image.content_type == "image/jpeg":
            return True
    return False


def check_group(shape):
    if shape.shape_type == 6:  # if shape is a group
        return True


def check_and_mark(shapes):
    for shape_id, shape in enumerate(shapes):
        if check_bitmap(shape):  # if bitmap, mark
            mark_shape(shape)
        if check_group(shape):  # if group, traverse recursively
            check_and_mark(shape.shapes)


def mark_bitmaps(prs):
    for slide_id, slide in enumerate(prs.slides):
        slide_number = slide_id   1
        check_and_mark(slide.shapes)


prs = Presentation("in.pptx")

mark_bitmaps(prs)

prs.save("out.pptx")
 

Комментарии:

1. как выглядит XML-файл формы? Что вы сделали о том, где живет SVG и почему он отображается в формате PNG?