使用PIL在图像上添加文本

时间:2013-05-04 10:44:54

标签: python django image python-imaging-library

我有一个加载图像的应用程序,当用户点击它时,会出现一个文本区域(使用jquery),用户可以在图像上写一些文字。应该在Image上添加哪个。

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

文字是Multiline。如何使用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();
    }   
});

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

我应该将它放在一个表单中,以便我可以在图像上获得textarea的坐标吗? 我想在用户点击时在图像上写文字并将其保存在图像上。

8 个答案:

答案 0 :(得分:137)

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

# 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

中提供的文字数量进行更改

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

答案 1 :(得分:13)

您可以在项目的根目录中创建目录“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)

答案 2 :(得分:6)

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

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

答案 3 :(得分:2)

在其他答案中未提及的一件事是检查文本大小。通常需要确保文本适合图像(例如,如果尺寸过大,则缩短文本)或确定绘制文本的位置(例如,对齐的文本顶部居中)。 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)) 

答案 4 :(得分:1)

首先,您必须下载一种字体类型,例如: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 :(得分:1)

使用Pillow,您还可以使用ImageDraw模块在图像上进行绘制。您可以绘制线,点,椭圆,矩形,弧形,位图,和弦,拼接,多边形,形状和文本。

my code : if(isset($_POST['btncuti'])){
// Validasi Cuti Tahunan
    if($_POST['jenis_cuti'] == "Cuti Tahunan"){

        $date1=date_create($_POST['mulai_tanggal']);
        $date2=date_create(date("Y-m-d"));
        $diff=date_diff($date1,$date2);

        if($diff->d >= 30){
        // if($diff->d == 30){
            $jeniscuti =  $_POST['jenis_cuti'];
            $alasancuti = $_POST['alasan_cuti'];
            $jumlahcuti = $_POST['jumlah_cuti'];
            $mulaitanggal = $_POST['mulai_tanggal'];
            $sampaitanggal = $_POST['sampai_tanggal'];
            $alamat1 = $_POST['alamat'];
            $nohp1 = $_POST['nohp'];

            $query="INSERT INTO cuti VALUES('null', '$jeniscuti','$alasancuti','$jumlahcuti','$mulaitanggal','$sampaitanggal','$alamat1','$nohp1', 'dalam proses', 'dalam proses', 'dalam proses', 'dalam proses', 'dalam proses', 'dalam proses','dalam proses','belum terbaca')";
            mysqli_query($koneksi_cuti, $query);
             if($query){
            echo "<script>alert('Pengajuan Cuti Berhasil')</script>";           
            echo "<script>window.open('user.php','_self')</script>";
            }
        }else {
            echo '<script type="text/javascript">alert("INFO:  Cuti Tahunan Harus H-30 Sebelum Bercuti");</script>';
        }
    }

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

答案 6 :(得分:1)

首先安装枕头

pip install pillow

示例

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)

答案 7 :(得分:-3)

要在图像文件上添加文本,只需复制/粘贴下面的代码

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