Reputation: 11
I am currently working with images and would like to know the fastest image processing library regarding annotating. I'm currently using this command:
convert orig.tif -background Red -density 300 -font /usr/share/fonts/truetype/msttcorefonts/Arial.ttf -pointsize 12 -gravity south -splice 0x150 -gravity southwest -annotate +50+50 "left corner" -gravity southeast -annotate +50+50 'right corner' +repage endorsed.tif
I'm calling this within the subprocess.call method in python. If I do this in command line, I get around 1 second total time:
real 0m0.162s
user 0m0.940s
sys 0m0.030s
My program averages 1.96 seconds:
[**copied_from** avg] 0:00:00.071887
[**mysql** avg] 0:00:00.000265
[**cropped** avg] 0:00:00.433935
[**rm** avg] 0:00:00.007758
[**copied_to** avg] 0:00:00.147880
[**endorsed** avg] 0:00:01.963496
[**mssql** avg] 0:00:00.000010
I'm not sure why there's a discrepancy between calling it from command line or through python's subprocess.call(cmd,shell=True). Either way, both of these are too slow.
I'm basically cropping and annotating images. It seems that cropping is fast enough with imagemagick's convert, but annotating is too slow. Does anyone know of a faster image library? I'm comfortable using python/ruby, but at this point, any solution that is faster would be helpful.
Thanks everyone.
Upvotes: 1
Views: 873
Reputation: 284602
Calling things from subprocess.call
is always going to have quite a bit of overhead compared to an actual shell (e.g. bash).
Have you tried using imagemagick's python bindings instead of calling it through subprocess
? (Edit: Cancel that... Those bindings are rather outdated. I don't know of any better ones, though... I haven't used imagemagick through python in a long time...)
You could also do this with PIL, though it's a bit less flexible and probably not significantly faster.
For whatever it's worth, here's the equivalent to your imagemagick command using PIL.
import Image
import ImageDraw
import ImageFont
rect_height = 150
im_orig = Image.open('orig.tif')
width, height = im_orig.size
im = Image.new('RGB', (width, height+rect_height))
im.paste(im_orig, (0,0))
width, height = im.size
dpi = 300
im.info['dpi'] = (dpi, dpi)
font_size = 12
font = ImageFont.truetype('/usr/share/fonts/truetype/arial.ttf',
int(dpi * font_size / 72.0))
draw = ImageDraw.Draw(im)
draw.rectangle([(0,height-rect_height), (width, height)], fill='red')
text = 'left corner'
text_width, text_height = font.getsize(text)
draw.text((50, height - 50 - text_height),
text, fill='black', font=font)
text = 'right corner'
text_width, text_height = font.getsize(text)
draw.text((width - 50 - text_width, height - 50 - text_height),
text, fill='black', font=font)
im.save('output.tif')
As you can see, it's a bit less convenient, but it does work. Also, this appears to be faster than imagemagick on my machine. The above script takes ~0.43 sec for a largish image, while your equivalent imagemagick command (just run directly from the shell) takes ~1.1 sec. Of course, imagemagick can do a lot more than PIL, but for simple image manipulation in python, PIL works pretty well.
(Edit: The speed difference is because PIL is saving the input tif (which is LZW compressed) as an uncompressed tif, while imagemagick saves it as an LZW compressed tiff, similar to the input.)
Upvotes: 2