#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?