简体   繁体   English

使用 PIL 在图像上添加文本

[英]Add Text on Image using PIL

I have an application that loads an Image and when the user clicks it, a text area appears for this Image (using jquery ), where user can write some text on the Image.我有一个加载图像的应用程序,当用户单击它时,会为该图像显示一个文本区域(使用jquery ),用户可以在其中在图像上写一些文本。 Which should be added on Image.应该在 Image 上添加。

After doing some research on it, I figured that PIL (Python Imaging Library ) can help me do this.在对它进行了一些研究之后,我认为PIL (Python 成像库)可以帮助我做到这一点。 So I tried couple of examples to see how it works and I managed to write text on an image.所以我尝试了几个例子来看看它是如何工作的,我设法在图像上写了文字。 But I think there is some difference when I try it using Python Shell and in web environment.但是我认为当我使用Python Shell和在 web 环境中尝试时会有一些不同。 I mean the text on the textarea is very big in px.我的意思是 textarea 上的文本在 px 中非常大。 How can I achieve the same size of text when using PIL as the one on the textarea?使用 PIL 时如何实现与 textarea 上相同大小的文本?

The text is Multiline.文本是多行的。 How can i make it multiline in image also, using PIL ?如何使用PIL使其在图像中也多行?

Is there a better way than using PIL?有没有比使用 PIL 更好的方法? I am not entirely sure, If this is the best implementation.我不完全确定,如果这是最好的实现。

html: html:

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

its the image being edited它正在编辑的图像

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

the jquery to add the textarea. jquery 添加textarea。 Also the text area is position:absolute and fixed size.文本区域也是位置:绝对和固定大小。

Should i place it inside a form so i can get coordinates of textarea on image?我应该把它放在一个表单中,这样我就可以获得图像上 textarea 的坐标吗? I want to write text on image when user clicks and save it on the image.我想在用户单击时在图像上写入文本并将其保存在图像上。

I think ImageFont module available in PIL should be helpful in solving text font size problem.我认为PIL可用的ImageFont模块应该有助于解决文本字体大小问题。 Just check what font type and size is appropriate for you and use following function to change font values.只需检查适合您的字体类型和大小,然后使用以下功能更改字体值。

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

So your code will look something similar to:所以你的代码看起来类似于:

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')

You might need to put some extra effort to calculate font size.您可能需要付出一些额外的努力来计算字体大小。 In case you want to change it based on amount of text user has provided in TextArea .如果您想根据用户在TextArea提供的文本量来更改它。

To add text wrapping (Multiline thing) just take a rough idea of how many characters can come in one line, Then you can probably write a pre-pprocessing function for your Text, Which basically finds the character which will be last in each line and converts white space before this character to new-line.要添加文本换行(多行内容),只需大致了解一行中可以出现多少个字符,然后您就可以为您的文本编写一个预处理函数,它基本上可以找到每行最后一个字符,然后将此字符之前的空白转换为换行符。

Even more minimal example (draws "Hello world!" in black and with the default font in the top-left of the image):更简单的例子(在图像的左上角用黑色和默认字体绘制“Hello world!”):

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

You can make a directory "fonts" in a root of your project and put your fonts (sans_serif.ttf) file there.您可以在项目的根目录中创建一个目录“fonts”,并将您的字体 (sans_serif.ttf) 文件放在那里。 Then you can make something like this:然后你可以做这样的事情:

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)

First, you have to download a font type...for example: https://www.wfonts.com/font/microsoft-sans-serif .首先,您必须下载字体类型...例如: https : //www.wfonts.com/font/microsoft-sans-serif

After that, use this code to draw the text:之后,使用此代码绘制文本:

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')

With Pillow, you can also draw on an image using the ImageDraw module.使用 Pillow,您还可以使用 ImageDraw 模块在图像上绘制。 You can draw lines, points, ellipses, rectangles, arcs, bitmaps, chords, pieslices, polygons, shapes and text.您可以绘制线条、点、椭圆、矩形、圆弧、位图、和弦、切片、多边形、形状和文本。

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')

we create an Image object with the new() method.我们使用 new() 方法创建一个 Image 对象。 This returns an Image object with no loaded image.这将返回一个没有加载图像的 Image 对象。 We then add a rectangle and some text to the image before saving it.然后我们在保存图像之前向图像添加一个矩形和一些文本。

One thing not mentioned in other answers is checking the text size.其他答案中没有提到的一件事是检查文本大小。 It is often needed to make sure the text fits the image (eg shorten the text if oversized) or to determine location to draw the text (eg aligned text top center).通常需要确保文本适合图像(例如,如果过大则缩短文本)或确定绘制文本的位置(例如对齐文本顶部中心)。 Pillow/PIL offers two methods to check the text size, one via ImageFont and one via ImageDraw. Pillow/PIL 提供了两种检查文本大小的方法,一种通过 ImageFont 和一种通过 ImageDraw。 As shown below, the font doesn't handle multiple lined, while ImageDraw does.如下所示,字体不处理多行,而 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)) 

First install pillow首先安装枕头

pip install pillow

Example例子

from PIL import Image, ImageDraw, ImageFont

image = Image.open('Focal.png')
width, height = image.size 

draw = ImageDraw.Draw(image)

text = 'https://devnote.in'
textwidth, textheight = draw.textsize(text)

margin = 10
x = width - textwidth - margin
y = height - textheight - margin

draw.text((x, y), text)

image.save('devnote.png')

# optional parameters like optimize and quality
image.save('optimized.png', optimize=True, quality=50)

I recently had to implement the same thing.我最近不得不实施同样的事情。 I have created a package on pypi which might come in handy: pynter我在pypi上创建了一个包,它可能会派上用场: pynter

You can add text to an image with this steps:您可以通过以下步骤向图像添加文本:

  1. Download an image: curl https://i.imgur.com/XQCKcC9.jpg -o ./image.jpg下载图片: curl https://i.imgur.com/XQCKcC9.jpg -o ./image.jpg

  2. Download a font: curl https://fonts.google.com/download?family=Roboto -o ./roboto.zip ; unzip ./roboto.zip -d ./Roboto下载字体: curl https://fonts.google.com/download?family=Roboto -o ./roboto.zip ; unzip ./roboto.zip -d ./Roboto curl https://fonts.google.com/download?family=Roboto -o ./roboto.zip ; unzip ./roboto.zip -d ./Roboto

  3. pip install pynter

from pynter.pynter import generate_captioned
font_path = './Roboto/Roboto-Regular.ttf'
image_path = './image.jpg'
im = generate_captioned('China lands rover on Mars'.upper(), image_path=image_path, size=(1080, 1350),
                        font_path=font_path, filter_color=(0, 0, 0, 40))
im.show()
im.convert('RGB').save('drawn_image.jpg')

This will be the results:这将是结果:

在此处输入图片说明

To add text on an image file, just copy/paste the code below要在图像文件上添加文本,只需复制/粘贴下面的代码

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM