Thêm văn bản trên hình ảnh bằng PIL


93

Tôi có một ứng dụng tải một Hình ảnh và khi người dùng nhấp vào nó, một vùng văn bản sẽ xuất hiện cho Hình ảnh này (đang sử dụng jquery), nơi người dùng có thể viết một số văn bản trên Hình ảnh. Cái nào nên được thêm vào Hình ảnh.

Sau khi thực hiện một số nghiên cứu về nó, tôi nhận ra rằng PIL(Thư viện ảnh Python) có thể giúp tôi làm điều này. Vì vậy, tôi đã thử một vài ví dụ để xem nó hoạt động như thế nào và tôi đã viết được văn bản trên một hình ảnh. Nhưng tôi nghĩ rằng có một số khác biệt khi tôi sử dụng nó Python Shellvà trong môi trường web. Ý tôi là văn bản trên textarea rất lớn bằng px. Làm cách nào để đạt được cùng kích thước văn bản khi sử dụng PIL như kích thước trên vùng văn bản?

Văn bản là Multiline. Làm thế nào tôi có thể làm cho nó cũng có nhiều dòng trong hình ảnh, sử dụng PIL?

Có cách nào tốt hơn là sử dụng PIL không? Tôi không hoàn toàn chắc chắn, Nếu đây là cách triển khai tốt nhất.

html:

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

nó là hình ảnh đang được chỉnh sửa

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

jquery để thêm vùng văn bản. Ngoài ra vùng văn bản là vị trí: kích thước tuyệt đối và cố định.

Tôi có nên đặt nó bên trong một biểu mẫu để tôi có thể nhận được tọa độ của vùng văn bản trên hình ảnh không? Tôi muốn viết văn bản trên hình ảnh khi người dùng nhấp vào và lưu nó trên hình ảnh.


Tại sao bạn muốn viết văn bản trên Hình ảnh bằng PIL (và tôi không chắc liệu PIL có giúp ích gì trong việc đó không). Nó không đủ tốt để bạn hiển thị văn bản trong lớp phủ, được sử dụng phổ biến nhất trong thanh trượt.
lalit

1
Tôi cần nó cho một dự án, tôi muốn hình ảnh được lưu. Pil có thể vẽ chữ trên ảnh bằng ImageDraw, không biết có cách khác không.
Apostolos

Nó sẽ hữu ích, Nếu bạn có thể cung cấp mã Python mà bạn đang sử dụng?
lalit

chưa được triển khai trong django. Tôi đã cố gắng xem PIL hoạt động như thế nào trong bảng điều khiển python tương tác. Muốn xem nó có hoạt động không trước tiên chuyển nó vào Django.
Apostolos

Biểu tượng $ trong mã của bạn là gì?
Mugen 10-10-18

Câu trả lời:


171

Tôi nghĩ mô-đun ImageFont có sẵn PILsẽ hữu ích trong việc giải quyết vấn đề kích thước phông chữ văn bản. Chỉ cần kiểm tra loại phông chữ và kích thước phù hợp với bạn và sử dụng chức năng sau để thay đổi giá trị phông chữ.

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

Vì vậy, mã của bạn sẽ trông giống như sau:

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

Bạn có thể cần phải nỗ lực thêm để tính toán kích thước phông chữ. Trong trường hợp bạn muốn thay đổi nó dựa trên lượng văn bản mà người dùng đã cung cấp TextArea.

Để thêm gói văn bản (Điều nhiều dòng) chỉ cần có ý tưởng sơ bộ về số lượng ký tự có thể có trong một dòng, Sau đó, bạn có thể viết một hàm tiền xử lý cho Văn bản của mình, về cơ bản tìm ký tự sẽ ở cuối mỗi dòng và chuyển đổi khoảng trắng trước ký tự này thành dòng mới.


1
Đó là suy nghĩ ban đầu của tôi. Vì vậy, tôi có cần phông chữ của mình trong một thư mục cụ thể trong máy chủ web của tôi để hoạt động không? Tôi nghĩ là có. Gói văn bản? Có một cách tiêu chuẩn hay tôi phải thực hiện một cách?
Apostolos

Bạn có thể giữ tệp phông chữ ở bất kỳ đâu trong máy chủ web của mình. Chỉ cần đảm bảo rằng đường dẫn bạn cung cấp là chính xác.
lalit

7
@lalit Tôi đã thử mã của bạn trên máy Windows và tôi gặp lỗi phông chữ self.font = core.getfont(file, size, index, encoding) IOError: cannot open resource. Làm cách nào để cung cấp đường dẫn đến tệp phông chữ?
LWZ

3
@LWZ, Để chạy đoạn mã trên, chỉ cần đảm bảo rằng tệp phông chữ nằm trong thư mục hiện tại mà bạn đang thực thi đoạn mã trên. Trong trường hợp bạn đang sử dụng nó vào chương trình của mình, chỉ cần chỉ định đường dẫn đầy đủ cho tệp của bạn, ví dụ: 'C: \ Windows \ Fonts \ sans-serif.ttf'. Điều khác mà bạn cần đảm bảo ở đây là cấp quyền đọc thích hợp cho tệp.
lalit

3
font = ImageFont.truetype ("./ arial.ttf", 30); draw.textsize (msg, font = font);
WeizhongTu

16

Bạn có thể tạo thư mục "phông chữ" trong thư mục gốc của dự án và đặt tệp phông chữ (sans_serif.ttf) của bạn ở đó. Sau đó, bạn có thể làm một cái gì đó như thế này:

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)

15

Ví dụ tối thiểu hơn nữa (vẽ "Hello world!" Bằng màu đen và với phông chữ mặc định ở trên cùng bên trái của hình ảnh):

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

6

Đầu tiên, bạn phải tải xuống một loại phông chữ ... ví dụ: https://www.wfonts.com/font/microsoft-sans-serif .

Sau đó, sử dụng mã này để vẽ văn bản:

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

4

Với Pillow, bạn cũng có thể vẽ hình ảnh bằng mô-đun ImageDraw. Bạn có thể vẽ đường thẳng, điểm, hình elip, hình chữ nhật, vòng cung, bitmap, hợp âm, pieslices, đa giác, hình dạng và văn bản.

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

chúng ta tạo một đối tượng Image bằng phương thức new (). Điều này trả về một đối tượng Hình ảnh không có hình ảnh được tải. Sau đó, chúng tôi thêm một hình chữ nhật và một số văn bản vào hình ảnh trước khi lưu nó.


3

Một điều không được đề cập trong các câu trả lời khác là kiểm tra kích thước văn bản. Thường cần đảm bảo văn bản phù hợp với hình ảnh (ví dụ: rút ngắn văn bản nếu quá khổ) hoặc xác định vị trí để vẽ văn bản (ví dụ: căn giữa văn bản trên cùng). Pillow / PIL cung cấp hai phương pháp để kiểm tra kích thước văn bản, một qua ImageFont và một qua ImageDraw. Như hình dưới đây, phông chữ không xử lý nhiều dòng, trong khi ImageDraw thì có.

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

-7

Để thêm văn bản vào tệp hình ảnh, chỉ cần sao chép / dán mã bên dưới

<?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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.