Open Image from requests.response.content - python

What I am trying to do is quite simple when dealing with a local file, but the problem comes when I try to do it with a remote URL.
Basically, I am trying to create a PIL image object from a file extracted from a URL. Of course, I could always fetch the URL and store it in a temporary file, then open it in an image object, but that seems very inefficient.
Here is what I have:
from PIL import Image
import requests
from io import BytesIO
response = requests.get(url)
img = Image.open(BytesIO(response.content))
So the Code is not returning the image if anyone knows.

Related

Check if file from incoming request is an image

I'm working on an application in which I need to upload images to an S3 bucket. The images come from HTTP requests inside form datas. I upload the images directly to S3 as objects (https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.put_object), without saving them on my backend for security purposes.
But for other security purposes, is there a way to check if my image object is actually representing an image before uploading it to S3?
Given a bytes object, the following solution worked out for me:
def validate_image(bytes_object):
import io
from PIL import Image
try:
Image.open(io.BytesIO(bytes_array))
except OSError:
print('Not a valid image')

Read text from images in python

Is there a way for read text from an image, some kind of text recognition method using python??
I need to read some images and get the text written on them.
I have been searching libraries such as pytesser, PIL and pillow, but anyone knows something else?
For windows and python 3.6.1
Thank you,
Marcus
The Google Vision API might help. It is able to pull out what objects are present in an image as well as other information (brands, colors, face detection etc). It can pull out text pretty reliably too.
https://cloud.google.com/vision/
Here is some example code from their website using the Python Client Library:
import io
import os
# Imports the Google Cloud client library
from google.cloud import vision
# Instantiates a client
vision_client = vision.Client()
# The name of the image file to annotate
file_name = os.path.join(
os.path.dirname(__file__),
'resources/wakeupcat.jpg')
# Loads the image into memory
with io.open(file_name, 'rb') as image_file:
content = image_file.read()
image = vision_client.image(
content=content)
# Performs label detection on the image file
labels = image.detect_labels()
print('Labels:')
for label in labels:
print(label.description)

Opening an Image From a URL with pgmagick

In pgmagick, you initialize an image like this:
Image('my_image.png')
I will be operating on files stored remotely on S3 and would rather not temporarily store them on disk. Is there any way to open an image file from a URL instead? When I try to simply replace the file name with the URL, I get an error: Unable to open file.
I'd like to be able to use a URL. If anyone has any suggestions on that or how to extend pgmagick to achieve it, I'd be elated.
The easiest way (in my mind) is to use the awesome requests library. You can fetch each image from the server one at a time, then open it with Image():
from StringIO import StringIO
import requests
from pgmagick import Image, Blob
r = requests.get('https://server.com/path/to/image1.png', auth=('user', 'pass'))
img = Image(Blob(StringIO(r.content)))
And that's all there is to it. Authentication is of course not required, but may be necessary depending on your S3 setup. Have fun!

How does Facebook share image base64 from Google App Engine

Im working with Google App Engine Project and I want use facebook share like this.
http://i.stack.imgur.com/uz52n.png
Im already read this
How does Facebook Sharer select Images and other metadata when sharing my URL?
but GAE cant upload physical Image, all image store in blob property in database as base64 so facebook share cant get the image :(
anyone had another idea for this problem ??
Facebook reads the og:image meta to resolve the image from your webpage. og:image don't allow data-URI image (base64 encoded).
You have to provide an image url in og:image, but with that url, you can make a workaround to simulate the behaviour of a direct image resolution and get the image from your appengine database.
This is a solution in python using Django, but the concept works for everything. The name of the image is here "key.png" where key is the key of the object containing the base64 stored image.
First, add an url to the list of django urls for your image resolution:
(r'^image/(?P<key>[^\.^/]+)\.png$', 'yourapp.views.image'),
Then in your views, get the key from the url, retrieve your object, base64 decode and send it back with the correct mimetype:
import base64
def image(request, key):
# get your object from database
f = YourImageObject.get(key)
# f.pic is the base64 encoded image
pic = f.pic[len("data:image/png;base64,"):] # remove the header
# base64 decode and respond with correct mimetype
return HttpResponse(base64.b64decode(pic), mimetype="image/png")

How do I display a PIL Image object in a template?

If a user uploads an image, and I resize it using PIL, I get a PIL Image object.
How do I display a PIL Image file in a template, before it has been saved to the database? Can it even be passed in as an image and rendered?
For a limited set of browsers, you can base64 encode the image and use inline images. See Embedding Base64 Images.
A solution that works for all browsers is an image tag referencing a view that returns the image.
[update]
All I want is for the user to submit the original image, and then be prompted by another form to input a caption for the image (with the resized image to the left of the caption field). Then when the user hits "submit" the image and the caption get saved in a model instance.
Well... When you use <img src="foo">, foo is always retrieved by a GET perhaps that is why it is not working - request.FILES will not be available in a GET request. If you open firebug or the chrome debug toolbar, in the network tab, you will see the POST request with the uploaded image and after that a GET request to fetch the image.
You have to save the image somewhere between both steps.
how else could i save it? I would love for it to be temporary. Do you think there's a really easy way to do this, or should I go look into those options?
Popular choices are redis and memcached. You can think of them as giant shared python dict with an expire date. If the images are small, like an avatar, you can also save the image data in a session variable.
Yes and no.
Yes, you can put the images as raw Base64 data. Here's a little script you can use to test this:
import Image
import base64
import StringIO
output = StringIO.StringIO()
im = Image.open("test.png") # Your image here!
im.save(output, format='PNG')
output.seek(0)
output_s = output.read()
b64 = base64.b64encode(output_s)
open("test.html","w+").write('<img src="data:image/png;base64,{0}"/>'.format(b64))
However, this is a really bad idea. With multiple thumbnails, your single HTML page might be 10MB+.
What you really should be doing is using a separate Django view to return images from PIL objects as PNG files, and then referencing that view in the img href attributes on your page.
You can embed base64 encoded images into an tag. So you could convert PIL image to base64 and then display it.
from PIL import Image
import StringIO
x = Image.new('RGB',(400,400))
output = StringIO.StringIO()
x.save(output, "PNG")
contents = output.getvalue().encode("base64")
output.close()
contents = contents.split('\n')[0]
Then show with:
<img src="data:image/png;base64,' + contents + ' />
Look to an example output.

Categories