Display an image read from a zip archive python - python

I want to create a comic archive reader in python as an exercise to teach myself more python but I've been having troubles trying to read different image files from a zip archive without extracting the files and then display them.
I found a website with an example (http://www.python-forum.org/pythonforum/viewtopic.php?f=4&t=3607) that could only display .gif images. The example uses PhotoImage (The Tkinter version not the PIL version) which can accept a 64bit encoded string instead of an actual file. From most of my research it looks like PIL is what I want to use to deal with images other than gif but I can't find a way to call PIL.ImageTk.PhotoImage in a similar way to the Tkinter.PhotoImage. to take a stream of data instead of an actual file.
Is there any way that I can hand the data received from zipfile.read() to PIL.ImageTk.PhotoImage? Is there another library I could use to handle the images? Tkinter is not a requirement for the program I'm writing so if there is a better widget framework that I should be using I don't mind changing.
EDIT:
So I figured a way to do this with PIL and tkinter.
z = zipfile.ZipFile("zipfile.zip", "r")
data = z.read(z.namelist()[0]) #Read in the first image data
dataEnc = StringIO(data) #Encode the raw data to be used by Image.open()
img = Image.open(dataEnc) #Open the image
pimg = ImageTk.PhotoImage(img) #Make tk compatible image

You can use PythonMagick to create an Image like so:
from PythonMagick import *
data = zipfile.read()
img = Image(Blob(data))
Then display it using wxPython as suggested in the PythonMagick readme under the "Display" section.

Related

Python crashing while opening a image

I am getting an image using an API call and eventually need to put the image into a PDF document using ReportLab. Python was crashing without any error messages when I tried canvas.drawImage method in ReportLab. In order to isolate the issue, I just tried opening the image using the Image class and Python still crashes. I can open the image manually using paint and the code does not error out when using other images, leading me to believe I am missing something while converting the binary to the image. I cannot share the images or the API. The definition of the result from the API is as follows.
<GetImageResponse xmlns="http://tempuri.org/">
<GetImageResult>base64Binary</GetImageResult>
<errorMessages>string</errorMessages>
</GetImageResponse>
'''
from zeep import Client
import base64
from PIL import Image, ImageTk
client=Client(wsdl='******.asmx?wsdl')
imgService=client.service.GetImage("***",****, "***********")
imgFile="imageTest.png"
base64_bytes = base64.b64encode(imgService.GetImageResult)
with open(imgFile, "wb") as fh:
fh.write(base64.decodebytes(base64_bytes))
image = Image.open(imgFile)
image.show()
'''
Can someone point me where I need to look? Thanks in advance for any pointers.

What is the correct way to compress a FileStorage object/image using PIL or another method?

I am wanting to compress an image I am receiving from a user before I send it off to an S3 bucket to be stored. Unfortunately for me, I haven't had to deal with images a lot. The image comes over as a FileStorage object and this is where my issue starts. I'm trying to use the PIL library to compress the image using the optimize option when you save your file using PIL. The only issue is I don't have a proper path to save this file. I tried to fake it out to no avail. Is there a proper way to generate a temporary directory/path to save the image just so I can compress it before I send it to the S3 bucket?
Here is the current simple code
file = request.files['filepond']
# file = Image.open(file)
# file = file.save('TestDirectory', file.format, optimize=True, quality=30)
print(file.filename)
print(file.content_type)
Thanks all!

Qt - Loading image with wrong extension

I'm currently working on a Qt program that works with images that are supplied by the users. One problem I've run into is that a lot of images are saved with the wrong extension - e.g. an image is saved in JPG format but has a PNG extension.
Qt doesn't seem to deal well with this. When I load an image like this into a QImage, the QImage fails to load. I've been looking through the docs, but I haven't come across anything relating to this.
Other programs I've used are able to correctly identify the image as a JPG despite the PNG extension, so there should be no reason for Qt to be unable to do this, but I'm not having any luck.
Any suggestions?
I solved this by using a QImageReader. An example is shown below using PySide.
First I created an instance of QImageReader and set it to read the format from the content.
image_reader = QtGui.QImageReader()
image_reader.setDecideFromContent(True)
This setting tells the reader to only look at the image's data to determine its format and not the extension.
Then I set the filename to the filename of the image I wanted to load and called read().
image_reader.setFileName(file_path_here)
image = image_reader.read()
Read returns a QImage object, so I proceeded with the rest of my code from there.

Python library which allows me to add text on top of images

do you know if there is a Python image library which allows me to add text on top of images?
PIL can do that (it's the standard image processing library for Python anyway).
on google: "PIL add text on top of images"
first result: http://python-catalin.blogspot.com/2010/06/add-text-on-image-with-pil-module.html
anyway, if you're looking for the library, you want to check into PIL

Text to a PNG on App Engine (Python)

Note: I am cross-posting this from App Engine group because I got no answers there.
As part of my site about Japan, I have a feature where the user can
get a large PNG for use as desktop background that shows the user's
name in Japanese. After switching my site hosting entirely to App
Engine, I removed this particular feature because I could not find any
way to render text to a PNG using the image API.
In other words, how would you go about outputting an unicode string on
top of an image of known dimensions (1024x768 for example), so that
the text will be as large as possible horizontally, and centered
vertically? Is there a way to do this is App Engine, or is there some
external service besides App Engine that could make this easier for
me, that you could recommend (besides running ImageMagick on your own
server)?
Solution #1. Pure Python image library.
You can try to bundle PyPNG with your application. PyPNG is a pure Python library to create PNG images. It depends on zlib module, which is allowed on AppEngine, so PyPNG should work on AppEngine. Just use StringIO objects instead of files and write PNG data to them.
Shamelessly adapting PyPNG example how to make a bitmap PNG image:
import png
from StringIO import StringIO
# bitmap data
s = ['110010010011',
'101011010100',
'110010110101',
'100010010011']
s = map(lambda x: map(int, x), s)
f = StringIO()
w = png.Writer(len(s[0]), len(s), greyscale=True, bitdepth=1)
w.write(f, s)
# binary PNG data
print f.getvalue()
I suspect suboptimal performance, but as far as I know there is no other way to generate images on GAE.
And you still need to figure out how to rasterize text to produce bitmap data. The easiest way, probably, is just to keep bitmaps of all the symbols around (essentially, using a bitmap font).
To render ASCII text with PyPNG take a look at texttopng script.
So, limitations are:
Probably slow (needs to be checked)
Glyph rasterization is to be addressed
Solution #2. Off-site text-to-image rendering.
Google AppEngine does not provide tools to render text as raster images, but Google Charts does. With a proper choice of parameters, the outline text chart just renders simple text to PNG images.
For example, http://chart.apis.google.com/chart?chst=d_text_outline&chld=000000|32|h|FFFFFF|_|Render text to image|with Google Charts.|Some Unicode too:|Здра́вствуйте|こんにちは|नमस्ते|你好|שלו produces this:
Limitations:
You cannot generate images bigger than 300000 pixels
Style and font customizations are limited
Some Unicode scripts are not available
White background only
I ran into this same problem with writing text to an image. The issue at hand is that any imaging libraries used on google app engine must be pure python, which rules out PIL.
PyBMP
PyBMP is a pure-python library that can do simple text rendering. From there you can use google's imaging library to composite the resulting bitmap onto your other pictures. There's some sample code below. The downside is the library lacks nicer features like anti-aliasing and fine control over fonts so the text that it renders looks kind of crappy. It also may or may not handle unicode well.
# Create the image
text_img = bmp.BitMap(300,35,bmp.Color.WHITE)
# bmpfont_Tw_Cen_MT_30 is a generated file using PyBMP's tool
text_img.setFont(bmpfont_Tw_Cen_MT_30.font_data)
text_img.setPenColor( bmp.Color.BLACK )
text_img.drawText(name, 0, 0)
After this you can use google's composite function on text_img.getBitmap() as you would any other image.
External Image Processing
If the text isn't good enough (it wasn't for my project), an alternative solution is to set up an external server on a service like Rackspace purely for image processing. Set up an HTTP handler that does your image processing with PIL, and then returns the resulting image. From there you can either
upload the result straight to your static file hosting server (like s3) or
get the generated-text image result with app engine's urlfetch library and do the rest of your compositing in app engine
Not pretty, but it gets the job done.
It's a bit too late but I was looking for the same. I managed to draw unicode string (here Devanagari) onto an image and save it as a '.png' file by doing the following:
# -*- coding: utf-8 -*-
import Image, ImageDraw, ImageFont
img = Image.new('L', (16,16), 255)
draw = ImageDraw.Draw(img)
text_to_draw = unicode('क','utf-8')
font = ImageFont.truetype('Path/to/font/file',12)
draw.text((2,2), text_to_draw, font = font)
del draw
img.save('image.png')
P.S. got help from other posts on stackoverflow
[Stop press: As comment suggests - this answer doesn't work in Googe App Engine.]
The Python Imaging Library (PIL) can accomplish this.
You can load in the image, draw Unicode text on it with the ImageDraw.text() function.
You may need to call ImageDraw.textsize() a few times with different font sizes to find thelargest font that will fit.
Finally, you can save the .png image to a file (or serve it back directly).
Test with large images if you are running it from within the context of a web-server, to make sure you can allocate sufficient memory to processs large PNG files.
(Have I answered your question appropriately? I don't know if PIL is an option from within the Google App Engine.)

Categories

Resources