PIL Draw.text and Lower Resolution - python

I have the following PIL code to print text in an image
import os, sys
import PIL
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
img = Image.open("one.jpg")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman.ttf",27)
draw.text((100, 100), "test test test", font=font)
img.save("out.jpg")
This works on one.jpg file. However on another test file called two.jpg, it doesn't print anything. From what I see, the only difference between two documents is the lower resolution on two.jpg. The file one.jpg is 200x200 dpi, two.jpg is 60x60 dpi.
How can I get draw.text to work in lower res?
Thanks,

You need to specify a color for the text:
import os
import sys
import ImageFont
import Image
import ImageDraw
img = Image.open("two.jpg")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman.ttf",27)
draw.text((100, 100), "test test test", font=font, fill = 'blue')
img.save("out.jpg")

Related

Problem in how to do image processing for some images - Error: AttributeError: type object 'Image' has no attribute 'open

I get an error when performing image processing for some images using python. The error is:
"AttributeError: type object 'Image' has no attribute 'open'".
I would be happy if you can review the code below and help me to fix this error. 
#imprint text on image
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
from IPython.display import Image
list2 = ['mydata/marketst670503.jpg','mydata/marketst8407.jpg','mydata/potsdamriot6805.jpg','mydata/rescue671221a.jpg']
outfile = 'sample-text.jpg'
for line in list2:
print (line)
img = Image.open(line)
draw = ImageDraw.Draw(img)
# font = ImageFont.truetype(<font-file>, <font-size>)
font = ImageFont.truetype("Colombia.ttf", 200)
draw.text((0, 0),"Sample Text",(255,0,0),font=font)
img.save(outfile)
display(Image(filename=outfile))
Notice! you have 2 imports under THE SAME NAME, overriding eachother.
I would make this change:
#mabe you replace the original import to a more nutral name..
import PIL.Image as Image
from PIL import ImageFont
from PIL import ImageDraw
from IPython.display import Image as DisplayImage # this line fixes your problem
list2 = ['mydata/marketst670503.jpg','mydata/marketst8407.jpg','mydata/potsdamriot6805.jpg','mydata/rescue671221a.jpg']
outfile = 'sample-text.jpg'
for line in list2:
print (line)
img = Image.open(line)
draw = ImageDraw.Draw(img)
# font = ImageFont.truetype(<font-file>, <font-size>)
font = ImageFont.truetype("Colombia.ttf", 200)
draw.text((0, 0),"Sample Text",(255,0,0),font=font)
img.save(outfile)
display(Image(filename=outfile))
and for next time, don't confuse yourself! choose a more nutral name then Image, and there won't be duplicates :)
*** Edited!***

How to use getpixel() in with PIL

Hello I am testing the getpixel() function in PIL but i keep getting "IndexError: image index out of range."
It works when i do this:
from PIL import ImageGrab, Image
image = ImageGrab.grab(bbox=(0, 0, 1920, 1080))
print(image.getpixel((10,10)))
But not when I do this:
from PIL import ImageGrab, Image
image = ImageGrab.grab(bbox=(1207, 301, 272, 537))
print(image.getpixel((10,10)))

Pillow Fails Rendering Urdu Text for Different Fonts

I am trying to generate image for some Urdu text using Pillow. Using the same code to generate normal English works like a charm but when I do the same with Urdu text things just does not go as smooth.
Following is the code and result when done with English:
from PIL import Image, ImageFont, ImageDraw
from matplotlib import pyplot as plt
import numpy as np
from bidi.algorithm import get_display
text_string = u'Hello how are you doing?'
img = Image.new('RGB', (720, 480))
draw = ImageDraw.Draw(img)
draw.text((25,40), text_string, fill='white')
img.save('pil_text_font.png')
And the resultant image:
Following is the code and result when done with Urdu:
from PIL import Image, ImageFont, ImageDraw
from matplotlib import pyplot as plt
import numpy as np
from bidi.algorithm import get_display
text_string = u'نیدرلینڈز کی ملکہ پاکستان آ رہی ہیں'
img = Image.new('RGB', (720, 480))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype('../UrduFontsDirectory' + data.iloc[14]['Path'], 25)
draw.text((25,40), text_string, fill='white', font=font)
img.save('pil_text_font.png')
And the resultant image:
Also I tried using Arabic Reshaper which resolved the alignment on rendering issue but yet some characters never get rendered:
from PIL import Image, ImageFont, ImageDraw
from matplotlib import pyplot as plt
import numpy as np
from bidi.algorithm import get_display
from arabic_reshaper import reshape
text_string = u'نیدرلینڈز کی ملکہ پاکستان آ رہی ہیں'
text_string = get_display(reshape(text_string))
img = Image.new('RGB', (720, 480))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype('../UrduFontsDirectory' + data.iloc[14]['Path'], 25)
draw.text((25,40), text_string, fill='white', font=font)
img.save('pil_text_font.png')
And the resultant iamge:
On further R&D found out that this is still an issue specifically for Urdu and no solution has been worked out for it yet:
As per described here.
However, I was able to find a work around for this using the good old .NET. For someone who might face similar problem may use following to generate Urdu text images (all of the fonts supported):
//Create the font using your font file
var modernFont = new PrivateFontCollection();
modernFont.AddFontFile("NafeesNaskh.ttf");//Load font from the font file
var font= new Font(modernFont.Families[0], 12);//The second argument is the font size
//first, create a dummy bitmap just to get a graphics object
Image img = new Bitmap(1, 1);
Graphics drawing = Graphics.FromImage(img);
//free up the dummy image and old graphics object
img.Dispose();
drawing.Dispose();
//create a new image of the right size
img = new Bitmap(500, 40);
drawing = Graphics.FromImage(img);
//paint the background
drawing.Clear(Color.Black);
//create a brush for the text
Brush textBrush = new SolidBrush(Color.White);
drawing.DrawString("نیدرلینڈز کی ملکہ پاکستان آ رہی ہیں", font, textBrush, new Rectangle(0, 0, img.Width, img.Height), new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
drawing.Save();
textBrush.Dispose();
drawing.Dispose();
string path = "./" + Id[i] + "_" + font.Name + ".jpg";
img.Save(path);
Also here is the resultant image:
Also it provides many more features like getting the image size for the text a given font and font size and also centering your content.
Image img = new Bitmap(1, 1);
Graphics drawing = Graphics.FromImage(img);
//Size of image for current text, font and font size
SizeF textSize = drawing.MeasureString("نیدرلینڈز کی ملکہ پاکستان آ رہی ہیں", font);
img.Dispose();
drawing.Dispose();
Also in the above example the center aligning code is as follows:
drawing.DrawString("نیدرلینڈز کی ملکہ پاکستان آ رہی ہیں", font, textBrush, new Rectangle(0, 0, img.Width, img.Height), new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
You can modify to have the text aligned to left, right, top or bottom as per your requirement.
Also for further details do refer to the documentation here.

How Tkinter could load png images with transparent backgrounds?

Some weeks ago i load a png image into my Tkinter Canvas and drawed with create_image, but now i can't do this anymore, i tried convert with ImageTk but png did not display
I have the following code:
load = Image.open("mouse.png")
self.img = ImageTk.PhotoImage(load)
self.draw.create_image(100,100,image=self.img,anchor = NW)
self.draw.image = self.img
I just need to present a png image
Try this
vSmallIco = (15, 15)
self.original = Image.open('.//data//img//plus.png')
resized = self.original.resize(vSmallIco, Image.ANTIALIAS)
self.plusIco = ImageTk.PhotoImage(resized)
self.medIco = ttk.Label(self.mf, image=self.plusIco, style='Main.TLabel')
this is done with this import
from PIL import Image, ImageTk
Also, please use a *.png image if you wish to use png.

Load image in tkinter from pygame surface in python 3

I would like to load an image in tkinter from a pygame surface and I am having a problem.
This is what I am currently trying:
image= pygame.image.tostring(surf, 'RGB')
tkimage= tkinter.PhotoImage(data= image)
canvas.create_image(0, 0, tkimage)
but I unfortunately get this error:
_tkinter.TclError: couldn't recognize image data
The PhotoImage class can only read GIF and PGM/PPM files, either directly from a file or as base64 encoded string.
You should use the Python Imaging Library for loading and creating the image for Tk.
Here's an example:
import pygame
from PIL import Image
import ImageTk
import Tkinter
# load image in pygame
pygame.init()
surf = pygame.image.load('bridge.png')
# export as string / import to PIL
image_str = pygame.image.tostring(surf, 'RGB') # use 'RGB' to export
w, h = surf.get_rect()[2:]
image = Image.fromstring('RGB', (w, h), image_str) # use 'RGB' to import
# create Tk window/widgets
root = Tkinter.Tk()
tkimage = ImageTk.PhotoImage(image) # use ImageTk.PhotoImage class instead
canvas = Tkinter.Canvas(root)
canvas.create_image(0, 0, image=tkimage)
canvas.pack()
root.mainloop()
------- UPDATE ------
import pygame
from pygame.locals import *
from PIL import Image
import ImageTk
import Tkinter
# load image in pygame
pygame.init()
surf = pygame.image.load('pic_temp.png') # you can use any Surface a Camers is also an Surface
mode = "RGB"
# export as string / import to PIL
image_str = pygame.image.tostring(surf, mode) # use 'RGB' to export
size = (640, 480)
#image = Image.fromstring(mode, size, image_str)
# use frombuffer() - fromstring() is no longer supported
image = Image.frombuffer(mode, size, image_str, 'raw', mode, 0, 1) # use 'RGB' to import
# create Tk window/widgets
root = Tkinter.Tk()
tkimage = ImageTk.PhotoImage(image) # use ImageTk.PhotoImage class instead
label = Tkinter.Label(root, image=tkimage)
label.pack()
root.mainloop()

Categories