Python 使用 PIL 在图像上添加文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16373425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add Text on Image using PIL
提问by Apostolos
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. Which should be added on Image.
我有一个加载图像的应用程序,当用户单击它时,会为该图像显示一个文本区域(使用jquery),用户可以在其中在图像上写一些文本。应该在 Image 上添加。
After doing some research on it, I figured that PIL(Python Imaging Library ) can help me do this. 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 Shelland in web environment. I mean the text on the textarea is very big in px. How can I achieve the same size of text when using PIL as the one on the textarea?
在对它做了一些研究之后,我认为PIL(Python Imaging Library)可以帮助我做到这一点。所以我尝试了几个例子来看看它是如何工作的,我设法在图像上写了文字。但是我认为当我尝试使用Python Shell和在网络环境中时会有一些差异。我的意思是 textarea 上的文本在 px 中非常大。使用 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? I am not entirely sure, If this is the best implementation.
有没有比使用 PIL 更好的方法?我不完全确定,如果这是最好的实现。
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. Also the text area is position:absolute and fixed size.
jquery 添加textarea。文本区域也是位置:绝对和固定大小。
Should i place it inside a form so i can get coordinates of textarea on image? I want to write text on image when user clicks and save it on the image.
我应该把它放在一个表单中,这样我就可以获得图像上 textarea 的坐标吗?我想在用户单击时在图像上写入文本并将其保存在图像上。
回答by lalit
I think ImageFontmodule available in PILshould be helpful in solving text font size problem. Just check what font type and size is appropriate for you and use following function to change font values.
我认为可用的ImageFont模块PIL应该有助于解决文本字体大小问题。只需检查适合您的字体类型和大小,然后使用以下功能更改字体值。
# 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.
要添加文本换行(多行内容),只需大致了解一行中可以出现多少个字符,然后您就可以为您的文本编写一个预处理函数,它基本上可以找到每行最后一个字符,然后将此字符之前的空白转换为换行符。
回答by svpp
You can make a directory "fonts" in a root of your project and put your fonts (sans_serif.ttf) file there. Then you can make something like this:
您可以在项目的根目录中创建一个目录“fonts”并将您的字体(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)
回答by Solomon Ucko
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
)
回答by Kumar S
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')
回答by Tamil Selvan S
With Pillow, you can also draw on an image using the ImageDraw module. You can draw lines, points, ellipses, rectangles, arcs, bitmaps, chords, pieslices, polygons, shapes and text.
使用 Pillow,您还可以使用 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')
we create an Image object with the new() method. This returns an Image object with no loaded image. We then add a rectangle and some text to the image before saving it.
我们使用 new() 方法创建一个 Image 对象。这将返回一个没有加载图像的 Image 对象。然后我们在保存图像之前向图像添加一个矩形和一些文本。
回答by lange
One thing not mentioned in other answers is checking the text size. It is often needed to make sure the text fits the image (e.g. shorten the text if oversized) or to determine location to draw the text (e.g. aligned text top center). Pillow/PIL offers two methods to check the text size, one via ImageFont and one via ImageDraw. As shown below, the font doesn't handle multiple lined, while ImageDraw does.
其他答案中没有提到的一件事是检查文本大小。通常需要确保文本适合图像(例如,如果过大则缩短文本)或确定绘制文本的位置(例如对齐文本顶部中心)。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))
回答by Ramsevak kumar
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>

