使用PIL在图像上添加文本

Apo*_*los 82 python django image python-imaging-library

我有一个加载图像的应用程序,当用户单击它时,会显示此图像的文本区域(使用jquery),用户可以在图像上写入一些文本.应该在Image上添加哪个.

在做了一些研究后,我认为PIL(Python Imaging Library)可以帮助我做到这一点.所以我尝试了几个例子来看它是如何工作的,我设法在图像上写文字.但我认为当我Python Shell在网络环境中使用它时会有一些区别.我的意思是textarea上的文字在px中非常大.当使用PIL作为textarea上的PIL时,如何获得相同大小的文本?

文字是Multiline.我怎样才能在图像中使用多线PIL?

有没有比使用PIL更好的方法?我不完全确定,如果这是最好的实施.

HTML:

<img src="images/test.jpg"/>
Run Code Online (Sandbox Code Playgroud)

正在编辑的图像

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

添加textarea的jquery.文本区域也是位置:绝对大小和固定大小.

我应该把它放在一个表格中,这样我就可以在图像上得到textarea的坐标吗?我想在用户点击时在图像上写文字并将其保存在图像上.

lal*_*lit 152

我认为ImageFont模块PIL应该有助于解决文本字体大小问题.只需检查适合您的字体类型和大小,并使用以下函数更改字体值.

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

所以你的代码看起来类似于:

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')
Run Code Online (Sandbox Code Playgroud)

您可能需要花费一些额外的精力来计算字体大小.如果您想根据用户提供的文本数量进行更改TextArea.

要添加文本换行(Multiline thing),只需粗略了解一行中可以有多少个字符,然后你可以为你的Text编写一个pre-pprocessing函数,它基本上可以找到每行中最后一个的字符.将此字符前的空格转换为换行符.

  • @lalit 我在 Windows 机器上尝试了你的代码,但我收到了字体 `self.font = core.getfont(file, size, index, encoding) IOError: cannot open resource` 的错误。如何提供字体文件的路径? (7认同)
  • @LWZ,要运行上面的代码,只需确保字体文件位于执行上述代码的当前目录中.如果您在程序中使用它,只需指定文件的完整路径,例如'C:\ Windows\Fonts\sans-serif.ttf'.您需要确保的其他事项是为文件提供适当的读取权限. (3认同)
  • font = ImageFont.truetype("./ arial.ttf",30); draw.textsize(msg,font = font); (3认同)

小智 14

您可以在项目的根目录中创建目录"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)
Run Code Online (Sandbox Code Playgroud)


小智 11

首先,您必须下载字体类型...例如: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')
Run Code Online (Sandbox Code Playgroud)


Sol*_*cko 8

更加简单的示例(用黑色绘制“ Hello world!”,图像的左上角带有默认字体):

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


Tam*_*n S 6

使用 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')
Run Code Online (Sandbox Code Playgroud)

我们使用 new() 方法创建一个 Image 对象。这将返回一个没有加载图像的 Image 对象。然后我们在保存图像之前向图像添加一个矩形和一些文本。


lan*_*nge 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)) 
Run Code Online (Sandbox Code Playgroud)


Fef*_*avi 6

首先安装枕头

pip install pillow
Run Code Online (Sandbox Code Playgroud)

例子

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)
Run Code Online (Sandbox Code Playgroud)