Добавить текст в изображение с помощью PIL

У меня есть приложение, которое загружает изображение, и когда пользователь нажимает на него, для этого изображения появляется текстовая область (с помощью jquery), где пользователь может написать текст на изображении. Который должен быть добавлен в изображение.

После некоторых исследований по этому вопросу я понял, что PIL (библиотека изображений Python) может помочь мне в этом. Поэтому я попробовал несколько примеров, чтобы увидеть, как это работает, и мне удалось написать текст на изображении. Но я думаю, что есть какая-то разница, когда я пытаюсь использовать его с помощью Python Shell и в веб-среде. Я имею в виду, что текст в текстовом поле очень большой в px. Как я могу достичь такого же размера текста при использовании PIL как в текстовом поле?

Текст является многострочным. Как я могу сделать его многострочным на изображении, используя PIL?

Есть ли лучший способ, чем использование PIL? Я не совсем уверен, если это лучшая реализация.

HTML:

<img src="images/test.jpg"/>

его редактируемое изображение

var count = 0;
$('textarea').autogrow();
$('img').click(function(){
    count = count + 1;
    if (count > 1){
        $(this).after('<textarea />');
        $('textarea').focus();
    }   
});

jquery, чтобы добавить текстовое поле. Также текстовая область является позицией: абсолютным и фиксированным размером.

Должен ли я разместить его внутри формы, чтобы я мог получить координаты textarea на изображении? Я хочу писать текст на изображении, когда пользователь нажимает и сохраняет его на изображении.

Ответ 1

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

# font = ImageFont.truetype(<font-file>, <font-size>)
# font-file should be present in provided path.
font = ImageFont.truetype("sans-serif.ttf", 16)

Таким образом, ваш код будет выглядеть примерно так:

from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw 

img = Image.open("sample_in.jpg")
draw = ImageDraw.Draw(img)
# font = ImageFont.truetype(<font-file>, <font-size>)
font = ImageFont.truetype("sans-serif.ttf", 16)
# draw.text((x, y),"Sample Text",(r,g,b))
draw.text((0, 0),"Sample Text",(255,255,255),font=font)
img.save('sample-out.jpg')

Возможно, вам придется приложить дополнительные усилия для расчета размера шрифта. Если вы хотите изменить его в зависимости от количества текста, которое пользователь предоставил в TextArea.

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

Ответ 2

Вы можете создать каталог "шрифты" в корневом каталоге вашего проекта и поместить туда свой файл шрифтов (sans_serif.ttf). Затем вы можете сделать что-то вроде этого:

fonts_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fonts')
font = ImageFont.truetype(os.path.join(fonts_path, 'sans_serif.ttf'), 24)

Ответ 3

Еще более минимальный пример (рисует "Hello world!" Черным шрифтом и шрифтом по умолчанию в верхнем левом углу изображения):

...
from PIL import ImageDraw
...
ImageDraw.Draw(
    image  # Image
).text(
    (0, 0),  # Coordinates
    'Hello world!',  # Text
    (0, 0, 0)  # Color
)

Ответ 4

Во-первых, вы должны загрузить тип шрифта... например: https://www.wfonts.com/font/microsoft-sans-serif.

После этого используйте этот код для рисования текста:

from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw 
img = Image.open("filename.jpg")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(r'filepath\..\sans-serif.ttf', 16)
draw.text((0, 0),"Draw This Text",(0,0,0),font=font) # this will draw text with Blackcolor and 16 size

img.save('sample-out.jpg')

Ответ 5

С Подушкой вы также можете рисовать изображение с помощью модуля ImageDraw. Вы можете рисовать линии, точки, эллипсы, прямоangularьники, дуги, растровые изображения, аккорды, кусочки, полигоны, фигуры и текст.

from PIL import Image, ImageDraw
blank_image = Image.new('RGBA', (400, 300), 'white')
img_draw = ImageDraw.Draw(blank_image)
img_draw.rectangle((70, 50, 270, 200), outline='red', fill='blue')
img_draw.text((70, 250), 'Hello World', fill='green')
blank_image.save('drawn_image.jpg')

мы создаем объект Image с помощью метода new(). Это возвращает объект Image без загруженного изображения. Затем мы добавляем прямоangularьник и текст к изображению перед его сохранением.

Ответ 6

Одна вещь, не упомянутая в других ответах, это проверка размера текста. Часто необходимо убедиться, что текст соответствует изображению (например, укоротить текст, если он увеличен) или определить место для рисования текста (например, выровненный текст по верхнему центру). Pillow/PIL предлагает два способа проверки размера текста, один с помощью ImageFont и один с помощью ImageDraw. Как показано ниже, шрифт не обрабатывает несколько строк, а ImageDraw -.

In [28]: im = Image.new(mode='RGB',size=(240,240))                                                            
In [29]: font = ImageFont.truetype('arial')
In [30]: draw = ImageDraw.Draw(im)
In [31]: t1 = 'hello world!'
In [32]: t2 = 'hello \nworld!'
In [33]: font.getsize(t1), font.getsize(t2) # the height is the same
Out[33]: ((52, 10), (60, 10)) 
In [35]: draw.textsize(t1, font), draw.textsize(t2, font)  # handles multi-lined text
Out[35]: ((52, 10), (27, 24)) 

Ответ 7

Чтобы добавить текст в файл изображения, просто скопируйте/вставьте приведенный ниже код

<?php
$source = "images/cer.jpg";
$image = imagecreatefromjpeg($source);
$output = "images/certificate".rand(1,200).".jpg";
$white = imagecolorallocate($image,255,255,255);
$black = imagecolorallocate($image,7,94,94);
$font_size = 30;
$rotation = 0;
$origin_x = 250;
$origin_y = 450;
$font = __DIR__ ."/font/Roboto-Italic.ttf";
$text = "Dummy";
$text1 = imagettftext($image,$font_size,$rotation,$origin_x,$origin_y,$black,$font,$text);
     imagejpeg($image,$output,99);
?> <img src="<?php echo $output; ?>"> <a href="<?php echo $output;    ?>" download="<?php echo $output; ?>">Download Certificate</a>