How can I print Hindi sentences(unicode) on image in Python?
Asked Answered
S

4

19

I have a file named "hindi.txt". It has contents as follows. I'm using Python3.5.

कामकाजी महिलाओं के लिए देश में दिल्ली असुरक्षित, सिक्किम सबसे बेहतर: रिपोर्ट
9 साल से अटकी राफेल डील मंजूर, 59000 Cr में भारत खरीदेगा 36 फाइटर प्लेन
WhatsApp को टक्कर देने आर्टिफिशियल इंटेलिजेंस के साथ आया गूगल का Allo मैसेंजर
उड़ी हमले पर 10 खुलासे: आर्मी बेस में 150 मीटर अंदर तक घुस आए थे जैश के आतंकी
उड़ी हमलाः भारत का कड़ा रुख देखकर PAK ने LoC से सटे शहरों में कैंसल 
PAK को आतंकी देश करार देने के लिए अमेरिकी संसद में पेश हुआ बिल

I'm opening this file in and then reading line by line. Then printing this text in image. My code snippet is shown as below.

from PIL import Image, ImageDraw, ImageFont, ImageOps
import os

with open("hindi.txt", "r") as filestream:
    cnum = 1
    astr = filestream.read().splitlines()

    font5 = ImageFont.truetype('/home/SunehraBharat/filestotweet/fonts/ARIALUNI.TTF', 26)

    MAX_W, MAX_H = 1500, 1500


    foreground_image = Image.new('RGB', (MAX_W, MAX_H), (0, 0, 0, 0))
    draw = ImageDraw.Draw(foreground_image)
    image_name = str(cnum) + "_" + "image.png"

    current_h, pad = 40, 14
    c = 1
    for txtline in astr:
        line = str(c) + ").  " + txtline
        #printing on console to check if lines are coming correctly.
        print(line)
        w, h = draw.textsize(line, font=font5)
        draw.text((10, current_h), line, font=font5, fill=(255,255,255,1))
        current_h += h + pad
        c = c + 1


    #saving image
    foreground_image.save(image_name)
    cnum = cnum + 1

Output on console due to print(line) statement- Correct

कामकाजी महिलाओं के लिए देश में दिल्ली असुरक्षित, सिक्किम सबसे बेहतर: रिपोर्ट
9 साल से अटकी राफेल डील मंजूर, 59000 Cr में भारत खरीदेगा 36 फाइटर प्लेन
WhatsApp को टक्कर देने आर्टिफिशियल इंटेलिजेंस के साथ आया गूगल का Allo मैसेंजर
उड़ी हमले पर 10 खुलासे: आर्मी बेस में 150 मीटर अंदर तक घुस आए थे जैश के आतंकी
उड़ी हमलाः भारत का कड़ा रुख देखकर PAK ने LoC से सटे शहरों में कैंसल 
PAK को आतंकी देश करार देने के लिए अमेरिकी संसद में पेश हुआ बिल

Now my Image Output:

enter image description here As you can compare now, output is not with respect to input. Few words are incorrect "सिक्किम" , "महिलाओं".

I have tried different fonts. But getting the same result everytime. Can you please help me. And let me know where I'm missing.

Skyward answered 22/9, 2016 at 5:28 Comment(7)
Looks like an offset with Unicode combining characters. Pillow always had some troubles with that. But at least, check if you are using the most recent version.Denary
Do you have any suggestion on the same? Version is latest.Skyward
Pillow latest version is : 5.2.0. Also there seems an open issues related with your problem: github.com/python-pillow/Pillow/issues/2255.Chukker
and github.com/python-pillow/Pillow/issues/3191Chukker
not working with the 3 libs - pillow - reported issue #2255, opencv - reported issue #118, & unicode_text_to_image_array - reported issue #2Ratio
Also doesn't work with wand - reported issue #374Ratio
actually when you see this printed on the terminal it has some unknown symbols thats why it gives incorrect output, but if you write the same lines in file you will get the correct line.Peridotite
C
15

There seems an open bug for rendering the hindi (Devanagari font) text.

https://github.com/python-pillow/Pillow/issues/3191

You may try with some other library like: pyvips (I do not find the API very intuitive, but it may work for you)

import pyvips


# To install 'pyvips' refers to https://pypi.org/project/pyvips/
#  1. Intall libvips shared library from https://jcupitt.github.io/libvips/install.html
#  2. Set the PATH variable.
#  3. run pip install pyvips

def generate_tweet_image():
    cnum = 1
    output_file = "tweet_file.png"
    text = u''
    with open("hindi.txt", "r", encoding='UTF-8') as filestream:
        for l in filestream.readlines():
            text = text + f'{cnum}) {l}'
            cnum += 1

    MAX_W, MAX_H = 1500, 1500

    # See for API https://jcupitt.github.io/pyvips/vimage.html#pyvips.Image.text

    # font file: ARIALUNI.TTF
    image = pyvips.Image.text(text, width=MAX_W, height=MAX_H, font='Arial Unicode MS', dpi=96)
    image.write_to_file(output_file)
    print(f'File Written at : {output_file}')


generate_tweet_image()

Output:

enter image description here

Hope this helps.

Chukker answered 12/8, 2018 at 11:13 Comment(3)
Thanks! This works really well. Was searching a solution with PIL but could not make it work.Payload
If someone is looking for transparent background behind the text: image = image.ifthenelse([255, 255, 255], [0, 0, 0], blend=True)Payload
Any solution for PHP?Hhour
P
3

Pillow 7.0.0 provides support for rendering complex font with raqm library

To check for support:

>>> from PIL import features
>>> print(features.check("raqm"))
True

If it returns False check if library is installed:

 /sbin/ldconfig -p | grep raqm
    libraqm.so.0 (libc6,x86-64) => /usr/lib/libraqm.so.0
    libraqm.so (libc6,x86-64) => /usr/lib/libraqm.so

To Install raqm in debian based distros: sudo apt-get install libraqm-dev

To use raqm as layout engine add layout_engine option while initializing font:

font = ImageFont.truetype("foo.ttf", size=90, layout_engine=ImageFont.LAYOUT_RAQM)

The above code is tested for: Hindi, Marathi, Gujrati and Telugu fonts.

Primate answered 30/3, 2020 at 18:12 Comment(0)
F
2

Installing Raqm, is the ultimate clean soon,check following steps

One of the following methods can be used for building Raqm:

  1. Raqm depends on the following libraries:

FreeType HarfBuzz FriBiDi

To install dependencies on Fedora:

sudo dnf install freetype-devel harfbuzz-devel fribidi-devel gtk-doc

To install dependencies on Ubuntu:

sudo apt-get install libfreetype6-dev libharfbuzz-dev libfribidi-dev \ gtk-doc-tools

On Mac OS X you can use Homebrew:

`export XML_CATALOG_FILES="/usr/local/etc/xml/catalog" # for the docs`

Once you have the source code and the dependencies, you can proceed to build. To do that, run the customary sequence of commands in the source code directory:

To do that, run the customary sequence of commands in the source code directory (configure file is not found in the package, The key was to run autogen.sh before):

$ ./autogen.sh
$ ./configure
$ make
$ make install

To run the tests:

$ make check

sudo ldconfig This step was needed!

Run the following test script: (Make sure the fonts are installed sudo apt install fonts-indic)


from PIL import Image, ImageFont, ImageDraw

im = Image.new("RGB",(160, 160))
draw = ImageDraw.Draw(im)

font_telugu = ImageFont.truetype("/usr/share/fonts/truetype/fonts-telu-extra/Pothana2000.ttf",50)
text_telugu = "నిత్య"

font_hindi = ImageFont.truetype("/usr/share/fonts/truetype/Gargi/Gargi.ttf",50)
text_hindi = "नित्य"

draw.text((10, 10), text_telugu, font=font_telugu)
draw.text((10, 90), text_hindi, font=font_hindi)
im.show()

  1. install tar file from releases If you downloaded the release tarball, you shouldn’t run ./autogen.sh at all, just run steps ./configure directly.

  2. for ubuntu >=18.04, you can install package directly- The requirements for libraqm are:

libc6   >= 2.14
libfreetype6    >= 2.4.2
libfribidi0 >= 1.0.0
libharfbuzz0b   >= 2.1.1

Install the raqm package Update the package index:

    sudo apt-get update

Install libraqm0 deb package:

sudo apt-get install libraqm0

You can test your installation by:

from PIL import features
print(features.check("raqm"))
# you should get True now
Fabricate answered 5/4, 2020 at 19:53 Comment(1)
For Windows, you can use pre-built DLLs for libraqm as shown here.Twi
S
0

Hey I had used pyvips to write hindi/devanagari text on an image using python.

First of all i installed pyvips, but when you import it will give you an error, so to overcome that issue you have to download file from pyvips and put it in your environment variable path and than you can put the text on image.

Actually I wrote article which contains step by step solution... I am sure this will help you.

https://www.infinitycodex.in/how-to-put-hindi-text-on-images-using

Spirt answered 6/3, 2022 at 11:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.