Как я могу получить размеры заполнителя изображения, чтобы изменить его размер при создании презентации и вставке изображения с помощью python-pptx? - PullRequest
0 голосов
/ 29 июня 2019

Я пытаюсь вставить изображение, которое было изменено в соответствии с размерами заполнителя изображения из шаблона с использованием python-pptx. Я не верю, что API имеет прямой доступ к этому из того, что я могу узнать в документации. Есть ли какие-либо предположения о том, как я мог бы сделать это, используя библиотеку или другое?

У меня есть работающий код, который вставит серию изображений в набор шаблонов слайдов для автоматического создания отчета с использованием Powerpoint.

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

def insert_images(slide, slide_num, images_path, image_df):

    """
    Insert images into a slide.
    :param slide: = slide object from Presentation class 
    :param slide_num: the template slide number for formatting
    :param images_path: the directory to the folder with all the images
    :param image_df: Pandas data frame regarding information of each image in images_path
    :return: None
    """

    placeholders = get_image_placeholders(slide)
    #print(placeholders)
    image_pool = image_df[image_df['slide_num'] == slide_num]

    try:
        assert len(placeholders) == len(image_pool.index)
    except AssertionError:
        print('Length of placeholders in slide does not match image naming.')
    i = 0
    for idx, image in image_pool.iterrows():
        #print(image)
        image_path = os.path.join(images_path, image.path)
        pic = slide.placeholders[placeholders[i]].insert_picture(image_path)
        #print(image.path)
        # TODO: Add resize - get dimensions of pic placeholder
        line = pic.line
        print(image['view'])
        if image['view'] == 'red':
            line.color.rgb = RGBColor(255, 0, 0)
        elif image['view'] == 'green':
            line.color.rgb = RGBColor(0, 255, 0)
        elif image['view'] == 'blue':
            line.color.rgb = RGBColor(0, 0, 255)
        else:
            line.color.rgb = RGBColor(0, 0, 0)
        line.width = Pt(2.25)
        i+=1

Проблема в том, что когда я вставляю изображение в заполнитель изображения, изображение обрезается, а не масштабируется. Я не хочу, чтобы пользователь знал размеры для жесткого кода в моем сценарии. Если используемое изображение является относительно большим, оно может обрезать очень большую часть и просто не может быть использовано.

1 Ответ

0 голосов
/ 29 июня 2019

Объект изображения, возвращаемый PicturePlaceholder.insert_picture, имеет ту же позицию и размер, что и заполнитель, из которого он получен.Он обрезается, чтобы полностью заполнить это пространство.Либо верхняя и нижняя части обрезаются, либо левая и правая стороны, в зависимости от соотношения сторон заполнителя и вставляемого изображения.Это то же самое поведение, которое демонстрирует PowerPoint при вставке изображения в заполнитель изображения.

Если вы хотите удалить обрезку, просто установите для всех значений обрезки значение 0:

picture = placeholder.insert_picture(...)
picture.crop_top = 0
picture.crop_left = 0
picture.crop_bottom = 0
picture.crop_right = 0

Это будетне меняйте положение (в верхнем левом углу), но почти всегда изменяйте размер, делая его шире или выше (но не оба).

Таким образом, это решает первую проблему легко, но, конечно, представляету вас есть второй, который заключается в том, как расположить изображение там, где вы хотите, и как правильно масштабировать его, не меняя соотношения сторон (растягивая или сжимая его).

Это во многом зависит от того, что вы 'Вы пытаетесь достичь и какой результат вы находите наиболее приятным.Вот почему это не автоматически;просто невозможно предсказать.

Вы можете найти "родную" ширину и высоту изображения следующим образом:

width, height = picture.image.size  # ---width and height are int pixel-counts

Оттуда вам нужно будет сравнить пропорцииисходный заполнитель и вставленное изображение, а также настройте ширину или высоту формы изображения.

Допустим, вы хотели сохранить ту же позицию, но сохранить ширину и высоту заполнителя в качестве соответствующих максимумов, так чтобы всекартинка помещается в пространство, но имеет «поле» внизу или справа:

available_width = picture.width
available_height = picture.height
image_width, image_height = picture.image.size
placeholder_aspect_ratio = float(available_width) / float(available_height)
image_aspect_ratio = float(image_width) / float(image_height)

picture.crop_top = 0
picture.crop_left = 0
picture.crop_bottom = 0
picture.crop_right = 0

# ---if the placeholder is "wider" in aspect, shrink the picture width while
# ---maintaining the image aspect ratio
if placeholder_aspect_ratio > image_aspect_ratio:
    picture.width = int(image_aspect_ratio * available_height)
# ---otherwise shrink the height
else:
    picture.height = int(available_width/image_aspect_ratio)

Это может быть разработано для «центрирования» изображения в исходном пространстве и, возможно, для использования «негативной обрезки»чтобы сохранить исходный размер заполнителя.

Я не проверял это, и вам может потребоваться внести некоторые изменения, но, надеюсь, это даст вам представление о том, как действовать дальше.Это было бы хорошо для извлечения в свою собственную функцию, например adjust_picture_to_fit(picture).

...