Getting a thumbnail image from google books api into a python variable - python

I can do this OK both in js and php but not in python. I'm trying to pull a thumbnail image from google books api into a python variable.
The text objects are fine eg
newTitle = (parsed_json['items'][0]['volumeInfo']['title'])
isbn10 = (parsed_json['items'][0]['volumeInfo']['industryIdentifiers'][1]['identifier'])
isbn13 = (parsed_json['items'][0]['volumeInfo']['industryIdentifiers'][0]['identifier'])
The image is supplied in the api as follows. (if you put the http// url into a browser you see the image):
"imageLinks": {
"smallThumbnail": "http://books.google.com/books/content?id=XUnNDwAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
"thumbnail": "http://books.google.com/books/content?id=XUnNDwAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
I have tried the simple:
myImage = (parsed_json['items'][0]['volumeInfo']['imageLinks'][thumbnail])
which doesn't work.
I have installed pillow to provide image management:
from PIL import Image
img = Image.open("parsed_json['items'][0]['volumeInfo']['imageLinks'][thumbnail]") or
img = Image.open(parsed_json['items'][0]['volumeInfo']['imageLinks'][thumbnail])
which doesn't work. I have tried more complex arrangements:
from PIL import Image
import requests
from io import BytesIO
response = requests.get(parsed_json['items'][0]['volumeInfo']['imageLinks'][thumbnail])
img = Image.open(BytesIO(response.content))
but nothing seems to work. I have tried many other variations on these attempts. I have also, unsuccessfully tried to load the text that points to the thumbnail to try another route. I am confident that the "['items'][0]['volumeInfo']['imageLinks'][thumbnail]" is correct though my only way of testing whether the variable is properly loaded is to save it or if the line of code isn't working.

I didn't have problems downloading and opening the image.
I have use the following code
import requests
from PIL import Image
image_url = "https://books.google.com/books/content?id=XUnNDwAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api"
r = requests.get(image_url)
with open("demo_image",'wb') as f:
f.write(r.content)
img = Image.open("demo_image")

Related

Using PIL module to open file from GCS

I am a beginner in programming, and this is my first little try. I'm currently facing a bottleneck, I would like to ask for the help. Any advice will be welcome. Thank you in advance!
Here is what I want to do:
To make a text detection application and extract the text for the further usage(for instance, to map some of the other relevant information in a data). So, I devided into two steps:
1.first, to detect the text
2.extract the text and use the regular expression to rearrange it for the data mapping.
For the first step, I use google vision api, so I have no probelm reading the image from google cloud storage(code reference 1):
However, when it comes to step two, I need a PIL module to open the file for drawing the text. When useing the methodImage.open(), it requries a path`. My question is how do I call the path? (code reference 2):
code reference 1:
from google.cloud import vision
image_uri = 'gs://img_platecapture/img_001.jpg'
client = vision.ImageAnnotatorClient()
image = vision.Image()
image.source.image_uri = image_uri ## <- THE PATH ##
response = client.text_detection(image=image)
for text in response.text_annotations:
print('=' * 30)
print(text.description)
vertices = ['(%s,%s)' % (v.x, v.y) for v in text.bounding_poly.vertices]
print('bounds:', ",".join(vertices))
if response.error.message:
raise Exception(
'{}\nFor more info on error messages, check: '
'https://cloud.google.com/apis/design/errors'.format(
response.error.message))
code reference 2:
from PIL import Image, ImageDraw
from PIL import ImageFont
import re
img = Image.open(?) <- THE PATH ##
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("simsun.ttc", 18)
for text in response.text_annotations[1::]:
ocr = text.description
bound=text.bounding_poly
draw.text((bound.vertices[0].x-25, bound.vertices[0].y-25),ocr,fill=(255,0,0),font=font)
draw.polygon(
[
bound.vertices[0].x,
bound.vertices[0].y,
bound.vertices[1].x,
bound.vertices[1].y,
bound.vertices[2].x,
bound.vertices[2].y,
bound.vertices[3].x,
bound.vertices[3].y,
],
None,
'yellow',
)
texts=response.text_annotations
a=str(texts[0].description.split())
b=re.sub(u"([^\u4e00-\u9fa5\u0030-u0039])","",a)
b1="".join(b)
regex1 = re.search(r"\D{1,2}Dist.",b)
if regex1:
regex1="{}".format(regex1.group(0))
.........
PIL does not have built in ability to automatically open files from GCS. you will need to either
Download the file to local storage and point PIL to that file or
Give PIL a BlobReader which it can use to access the data:
from PIL import Image
from google.cloud import storage
storage_client = storage.Client()
bucket = storage_client.bucket('img_platecapture')
blob = bucket.get_blob('img_001.jpg') # use get_blob to fix generation number, so we don't get corruption if blob is overwritten while we read it.
with blob.open() as file:
img = Image.open(file)
# ...

How can I fetch an image from a URL returned from the Unsplash API?

import requests
def linkFetch():
url = "https://api.unsplash.com/photos/random/?client_id=MyAccessKey"
response = requests.get(url)
data = response.json()["urls"]["raw"]
return data
def imageFetch(data):
print(data)
imageFetch(linkFetch())
Here my code runs and fetches a url for an image but how can I automatically open the photo in small window. the linkFetch() function actually gets the image link and I want imageFetch() to actually open the photo. I'm new to using apis so any help will be useful. I already tried using another request.get() but I may have used it incorrectly. Other solutions seem to want to download the image indefinitely where I want to just open it.
Note: MyAccessKey replaces my actual key
You have to first get the image data by sending a request then pass it to the pillow package to display the image.
from io import BytesIO
from PIL import Image
import requests
img_url = imageFetch(linkFetch())
response = requests.get(img_url)
img = Image.open(BytesIO(response.content))
img.show()

Image processing after upload with Python Bottle

Context
I have made a simple web app for uploading content to a blog. The front sends AJAX requests (using FormData) to the backend which is Bottle running on Python 3.7. Text content is saved to a MySQL database and images are saved to a folder on the server. Everything works fine.
Image processing and PIL/Pillow
Now, I want to enable processing of uploaded images to standardise them (I need them all resized and/or cropped to 700x400px).
I was hoping to use Pillow for this. My problem is creating a PIL Image object from the file object in Bottle. I cannot initialise a valid Image object.
Code
# AJAX sends request to this route
#post('/update')
def update():
# Form data
title = request.forms.get("title")
body = request.forms.get("body")
image = request.forms.get("image")
author = request.forms.get("author")
# Image upload
file = request.files.get("file")
if file:
extension = file.filename.split(".")[-1]
if extension not in ('png', 'jpg', 'jpeg'):
return {"result" : 0, "message": "File Format Error"}
save_path = "my/save/path"
file.save(save_path)
The problem
This all works as expected, but I cannot create a valid Image object with pillow for processing. I even tried reloading the saved image using the save path but this did not work either.
Other attempts
The code below did not work. It caused an internal server error, though I am having trouble setting up more detailed Python debugging.
path = save_path + "/" + file.filename
image_data = open(path, "rb")
image = Image.open(image_data)
When logged manually, the path is a valid relative URL ("../domain-folder/images") and I have checked that I am definitely importing PIL (Pillow) correctly using PIL.PILLOW_VERSION.
I tried adapting this answer:
image = Image.frombytes('RGBA', (128,128), image_data, 'raw')
However, I won’t know the size until I have created the Image object. I also tried using io:
image = Image.open(io.BytesIO(image_data))
This did not work either. In each case, it is only the line trying to initialise the Image object that causes problems.
Summary
The Bottle documentation says the uploaded file is a file-like object, but I am not having much success in creating an Image object that I can process.
How should I go about this? I do not have a preference about processing before or after saving. I am comfortable with the processing, it is initialising the Image object that is causing the problem.
Edit - Solution
I got this to work by adapting the answer from eatmeimadanish. I had to use a io.BytesIO object to save the file from Bottle, then load it with Pillow from there. After processing, it could be saved in the usual way.
obj = io.BytesIO()
file.save(obj) # This saves the file retrieved by Bottle to the BytesIO object
path = save_path + "/" + file.filename
# Image processing
im = Image.open(obj) # Reopen the object with PIL
im = im.resize((700,400))
im.save(path, optimize=True)
I found this from the Pillow documentation about a different function that may also be of use.
PIL.Image.frombuffer(mode, size, data, decoder_name='raw', *args)
Note that this function decodes pixel data only, not entire images.
If you have an entire image file in a string, wrap it in a BytesIO object, and use open() to load it.
Use StringIO instead.
From PIL import Image
try:
import cStringIO as StringIO
except ImportError:
import StringIO
s = StringIO.StringIO()
#save your in memory file to this instead of a regular file
file = request.files.get("file")
if file:
extension = file.filename.split(".")[-1]
if extension not in ('png', 'jpg', 'jpeg'):
return {"result" : 0, "message": "File Format Error"}
file.save(s)
im = Image.open(s)
im.resize((700,400))
im.save(s, 'png', optimize=True)
s64 = base64.b64encode(s.getvalue())
From what I understand, you're trying to resize the image after it has been saved locally (note that you could try to do the resize before it is saved). If this is what you want to achieve here, you can open the image directly using Pillow, it does the job for you (you do not have to open(path, "rb"):
image = Image.open(path)
image.resize((700,400)).save(path)

Capture a web in image with OpenCV

I want to do a practice that consists of capturing webs in jpg, but it did not just work (I am newbie), this is the code I use.
import numpy as np
import urllib
import cv2
def url_to_image("http://www.hereiputweb.com"):
resp = urllib.urlopen("http://www.hereiputweb.com")
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
return image
The code I got it from a manual but it gives me fault in the line:
def url_to_image("http://www.hereiputweb.com"):
I think I indicated the web incorrectly, very far I should not be .. tried several forms but nothing .. what do I do wrong?
regards
There is a really brief tutorial (https://docs.python.org/3/tutorial/).
The relevant part would be https://docs.python.org/3/tutorial/controlflow.html#defining-functions
So, you should define your function as follows:
def url_to_image(url):
resp = urllib.urlopen(url)
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
return image
I have not checked the implementation works ;)
Then you can use your function:
url = "http://www.hereiputweb.com"
my_image = url_to_image(url)
The problem is not with your implementation, it's with your URL!
This method require a functioning URL that returns an image. The URL you're using is not an image.
Try using an URL of an image (e.g: some URLs that end with .jpg) and it shall work!
Remember that the URL must be on-line!

Entering the url in the browser, downloads the image automatically. How to write a python script to download such images?

url="https://images.data.gov.sg/api/traffic-images/2016/02/96128cfd-ab9a-4959-972e-a5e74bb149a9.jpg"
I am trying this:
import urllib
url="https://images.data.gov.sg/api/traffic-images/2016/02/96128cfd-ab9a-4959-972e-a5e74bb149a9.jpg"
IMAGE=url.rsplit("/")[-1]
urllib.urlretrieve(url,IMAGE)
Image is downloaded in the destination folder after the execution, but it is corrupt.
"Could not load image"; error pops up.
It might be because the domain that you are trying to reach has restrictions over download policy. Check this one out, hope it helps! https://stackoverflow.com/a/8389368/2539771
import urllib
URL = "https://images-na.ssl-images-amazon.com/images/I/714tx9QbaKL.SL1500.jpg"
urllib.urlretrieve(URL, "sample.png")
from PIL import Image
img = Image.open('/home/sks/sample.png')
img.show()

Categories

Resources