Tambahkan Teks pada Gambar menggunakan PIL

94

Saya memiliki aplikasi yang memuat Gambar dan ketika pengguna mengkliknya, area teks muncul untuk Gambar ini (menggunakan jquery ), di mana pengguna dapat menulis beberapa teks pada Gambar. Yang harus ditambahkan pada Gambar.

Setelah melakukan beberapa penelitian tentang itu, saya pikir PIL(Python Imaging Library) dapat membantu saya melakukan ini. Jadi saya mencoba beberapa contoh untuk melihat cara kerjanya dan saya berhasil menulis teks pada gambar. Tapi menurut saya ada beberapa perbedaan saat saya coba pakaiPython Shell dan di lingkungan web. Maksud saya, teks pada area teks sangat besar dalam px. Bagaimana saya bisa mendapatkan ukuran teks yang sama saat menggunakan PIL seperti yang ada di textarea?

Teksnya Multiline. Bagaimana saya bisa membuatnya multiline dalam gambar juga, menggunakanPIL ?

Apakah ada cara yang lebih baik daripada menggunakan PIL? Saya tidak sepenuhnya yakin, apakah ini implementasi terbaik.

html:

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

gambarnya sedang diedit

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

jquery untuk menambahkan textarea. Juga area teks adalah posisi: ukuran absolut dan tetap.

Haruskah saya meletakkannya di dalam formulir sehingga saya bisa mendapatkan koordinat textarea pada gambar? Saya ingin menulis teks pada gambar ketika pengguna mengklik dan menyimpannya pada gambar.

Apostolos
sumber
Mengapa Anda ingin menulis teks pada Gambar menggunakan PIL (dan saya tidak yakin apakah PIL membantu dalam hal itu). Bukankah cukup baik bagi Anda untuk menampilkan teks dalam overlay, yang paling sering digunakan di slider.
lalit
1
Saya membutuhkannya untuk sebuah proyek, saya ingin gambarnya disimpan. Pil dapat menggambar teks pada gambar menggunakan ImageDraw, tidak tahu apakah ada cara lain.
Apostolos
Akan sangat membantu, Jika Anda dapat memberikan kode Python yang Anda gunakan?
lalit
belum diimplementasikan di django. Saya mencoba melihat bagaimana PIL bekerja di konsol python interaktif. Ingin melihat apakah ini berhasil dulu dan kemudian mentransfernya di Django.
Apostolos
Apa simbol $ dalam kode Anda?
Mugen

Jawaban:

173

Saya pikir modul ImageFont yang tersedia di PILharus membantu dalam memecahkan masalah ukuran font teks. Cukup periksa jenis dan ukuran font yang sesuai untuk Anda dan gunakan fungsi berikut untuk mengubah nilai font.

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

Jadi kode Anda akan terlihat seperti ini:

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

Anda mungkin perlu melakukan upaya ekstra untuk menghitung ukuran font. Jika Anda ingin mengubahnya berdasarkan jumlah teks yang telah disediakan penggunaTextArea .

Untuk menambahkan pembungkusan teks (Multiline thing) ambil gambaran kasar tentang berapa banyak karakter yang bisa datang dalam satu baris, Kemudian Anda mungkin dapat menulis fungsi pra-pemrosesan untuk Teks Anda, Yang pada dasarnya menemukan karakter yang akan terakhir di setiap baris dan mengonversi spasi sebelum karakter ini menjadi baris baru.

lalit
sumber
1
Itulah pemikiran awal saya. Jadi, apakah saya perlu font saya berada di folder tertentu di server web saya agar berfungsi? Saya rasa ya. Teks pembungkus? Apakah ada cara standar atau haruskah saya menerapkannya?
Apostolos
Anda dapat menyimpan file font di mana saja di server web Anda. Pastikan saja jalur yang Anda berikan sudah benar.
lalit
7
@lalit Saya mencoba kode Anda pada mesin Windows dan saya mendapat kesalahan untuk font self.font = core.getfont(file, size, index, encoding) IOError: cannot open resource. Bagaimana saya bisa memberikan jalur ke file font?
LWZ
3
@LWZ, Untuk menjalankan kode di atas, cukup pastikan bahwa file font ada di direktori saat ini di mana Anda menjalankan kode di atas. Jika Anda menggunakannya ke dalam program Anda, cukup tentukan path lengkap untuk file Anda misalnya 'C: \ Windows \ Fonts \ sans-serif.ttf'. Hal lain yang perlu Anda pastikan di sini adalah memberikan izin baca yang sesuai ke file tersebut.
lalit
3
font = ImageFont.truetype ("./ arial.ttf", 30); draw.textsize (msg, font = font);
WeizhongTu
16

Anda dapat membuat direktori "font" di root proyek Anda dan meletakkan file font (sans_serif.ttf) di sana. Kemudian Anda bisa membuat sesuatu seperti ini:

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)
svpp
sumber
15

Contoh yang lebih minimal lagi (gambar "Hello world!" Dalam warna hitam dan dengan font default di kiri atas gambar):

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

Pertama, Anda harus mengunduh jenis font ... misalnya: https://www.wfonts.com/font/microsoft-sans-serif .

Setelah itu, gunakan kode ini untuk menggambar teks:

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')
Kumar S
sumber
5

Dengan Pillow, Anda juga bisa menggambar pada gambar menggunakan modul ImageDraw. Anda dapat menggambar garis, titik, elips, persegi panjang, busur, bitmap, akord, pieslice, poligon, bentuk, dan teks.

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

kita membuat objek Image dengan metode new (). Ini mengembalikan objek Gambar tanpa gambar yang dimuat. Kami kemudian menambahkan persegi panjang dan beberapa teks ke gambar sebelum menyimpannya.

Tamil Selvan S.
sumber
4

Satu hal yang tidak disebutkan dalam jawaban lain adalah memeriksa ukuran teks. Seringkali diperlukan untuk memastikan teks sesuai dengan gambar (misalnya, mempersingkat teks jika ukurannya terlalu besar) atau untuk menentukan lokasi untuk menggambar teks (misalnya teks rata tengah atas). Pillow / PIL menawarkan dua metode untuk memeriksa ukuran teks, satu melalui ImageFont dan satu melalui ImageDraw. Seperti yang ditunjukkan di bawah ini, font tidak menangani banyak garis, sedangkan ImageDraw melakukannya.

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)) 
lange
sumber
Terima kasih telah menyoroti perbedaan ini. Saya memang sedang mencari ukuran teks yang tepat dalam beberapa baris.
fcole90
-9

Untuk menambahkan teks pada file gambar, cukup salin / tempel kode di bawah ini

<?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>
Ramsevak kumar
sumber