Додайте текст на зображення за допомогою PIL


94

У мене є програма, яка завантажує Зображення, і коли користувач клацає на ньому, для цього Зображення з’являється текстова область (за допомогою jquery), де користувач може написати якийсь текст на Зображенні. Що слід додати на Image.

Провівши деякі дослідження, я зрозумів, що PIL(бібліотека зображень Python) може допомогти мені це зробити. Тому я спробував кілька прикладів, щоб побачити, як це працює, і мені вдалося написати текст на зображенні. Але я думаю, що є певна різниця, коли я намагаюся це використовувати Python Shellі в веб-середовищі. Я маю на увазі, що текст на текстовій області дуже великий у пікселях. Як я можу досягти такого ж розміру тексту, коли використовую 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 для додавання тексту. Також область тексту - це положення: абсолютний та фіксований розмір.

Чи слід розміщувати його всередині форми, щоб я міг отримати координати тексту на зображенні? Я хочу написати текст на зображенні, коли користувач клацає, і зберегти його на зображенні.


Чому ви хочете написати текст на зображенні за допомогою PIL (і я не впевнений, чи допомагає PIL у цьому). Хіба вам недостатньо показувати текст у накладенні, який найчастіше використовується у повзунках.
лаліт

1
Він потрібен мені для проекту. Я хочу, щоб зображення було збережено. Піл може намалювати текст на зображенні за допомогою ImageDraw, не знаю, чи існує інший спосіб.
Апостолос

Це буде корисно, якщо ви можете надати код Python, який ви використовуєте?
лаліт

ще не реалізовано в django. Я спробував побачити, як працює PIL в інтерактивній консолі python. Хочете перевірити, чи працює це спочатку, а потім перенести його в Django.
Апостолос

Який символ $ у вашому коді?
Mugen

Відповіді:


173

Я думаю, що модуль 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.

Щоб додати обтікання тексту (багаторядкова річ), просто візьміть приблизне уявлення про те, скільки символів може бути в одному рядку. Тоді ви, можливо, можете написати функцію попередньої обробки для вашого тексту, яка в основному знаходить символ, який буде останнім у кожному рядку перетворює пробіл перед цим символом у новий рядок.


1
Це моя початкова думка. Тож чи потрібні мої шрифти в певній папці мого веб-сервера, щоб працювати? Я думаю, що так. Обтікання текстом? Чи існує стандартний спосіб чи я повинен його застосувати?
Апостолос

Ви можете зберігати файл шрифту в будь-якому місці веб-сервера. Просто переконайтеся, що шлях, який ви надаєте, правильний.
лаліт

7
@lalit Я спробував ваш код на машині Windows, і я отримав помилку для шрифту self.font = core.getfont(file, size, index, encoding) IOError: cannot open resource. Як я можу вказати шлях до файлу шрифту?
LWZ

3
@LWZ, Щоб запустити наведений вище код, просто переконайтеся, що файл шрифту знаходиться в поточному каталозі, в якому ви виконуєте вказаний вище код. Якщо ви використовуєте його у своїй програмі, просто вкажіть повний шлях до вашого файлу, наприклад, "C: \ Windows \ Fonts \ sans-serif.ttf". Інше, що вам потрібно переконатись тут, - це надати належні дозволи на читання файлу.
lalit

3
font = ImageFont.truetype ("./ arial.ttf", 30); draw.textsize (msg, font = font);
WeizhongTu

16

Ви можете створити каталог "шрифти" у кореневій частині вашого проекту та помістити туди файл шрифтів (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)

15

Ще більш мінімальний приклад (малює "Hello world!" Чорним кольором і зі шрифтом за замовчуванням у верхньому лівому куті зображення):

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

7

По-перше, вам потрібно завантажити тип шрифту ... наприклад: 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. Ви можете малювати лінії, точки, еліпси, прямокутники, дуги, растрові зображення, акорди, пієслики, багатокутники, фігури та текст.

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 без завантаженого зображення. Потім ми додаємо до зображення прямокутник та трохи тексту перед збереженням.


3

Одне, про що не згадується в інших відповідях, - це перевірка розміру тексту. Часто це потрібно для того, щоб переконатися, що текст підходить до зображення (наприклад, скоротити текст, якщо надто великий), або щоб визначити місце для малювання тексту (наприклад, вирівняний текст зверху по центру). 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)) 

-9

Щоб додати текст до файлу зображення, просто скопіюйте / вставте код нижче

<?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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.