How can I resize image with quality without saving image in Python? - image-resizing

I use this code but it need to save
from PIL import Image
import requests
from io import BytesIO
response = requests.get(url)
img = Image.open(BytesIO(response.content))
image = img.resize((W, H), Image.ANTIALIAS)
image.save('De7k.jpeg', optimize=True, quality=Quality)

If you would like to "save" the file while keeping it in memory instead of writing a file to disk, you can write it to another BytesIO object.
from PIL import Image
import requests
from io import BytesIO
response = requests.get(url)
img = Image.open(BytesIO(response.content))
image = img.resize((W, H), Image.ANTIALIAS)
output = BytesIO()
image.save(output, format="JPEG", optimize=True, quality=Quality)

Related

Writing image into a PDF File

Trying to write an image into a pdf file at a specific location. Here in this code "Reporting.pdf" file contains a template where I have to paste my image. While running this code, the output pdf file remains the same as "Reporting.pdf" file i.e. the image doesn't get written on the pdf. Can you help me resolve this issue?
from PyPDF2 import PdfFileWriter, PdfFileReader
from reportlab.pdfgen import canvas
from io import BytesIO
import os
THIS_FOLDER = os.path.dirname(os.path.abspath(__file__))
imgPath = os.path.join(THIS_FOLDER, 'child.png')
print(imgPath)
# Using ReportLab to insert image into PDF
imgTemp = BytesIO()
imgDoc = canvas.Canvas(imgTemp)
# Draw image on Canvas and save PDF in buffer
# imgPath = "/home/sachin/Files/child-image.jpeg"
imgDoc.drawImage(imgPath, 399, 760, 160, 160) ## at (399,760) with size 160x160
imgDoc.save()
print(imgDoc)
# Use PyPDF to merge the image-PDF into the template
page = PdfFileReader("Reporting.pdf","rb").getPage(0)
overlay = PdfFileReader(BytesIO(imgTemp.getvalue())).getPage(0)
page.mergePage(overlay)
#Save the result
output = PdfFileWriter()
output.addPage(page)
pdfOutput = open('output_file101.pdf', 'wb')
output.write(pdfOutput)
pdfOutput.close()
You can't just do a drawImage with a filepath.
Consider using an ImageReader:
from reportlab.lib.utils import ImageReader
reader = ImageReader(imgPath)
imgDoc.drawImage(reader, ...)

Read a .jpg from RAM

from io import StringIO
from PIL import Image
import requests
response = requests.get(image.url)
# Works fine, but requests a disk write.
f = open('tmp.jpg', 'bw')
f.write(response.content)
img = Image.open('tmp.jpg')
# Fails with `OSError: cannot identify image file <_io.StringIO object at 0x7fb666238a68>`
#file = StringIO(str(response.content))
#img = Image.open(file)
I am trying to run the code from this tutorial but in python3. The commented out version is the closest I have gone to the original idea of "get an image from the network into RAM and work with that". I don't mind using cv2 if easier. How do I write this code pythonically and efficiently?
As Mark Setchell said, you likely want BytesIO not StringIO.
from io import BytesIO
from PIL import Image
import requests
response = requests.get(image.url)
file = BytesIO(response.content)
img = Image.open(file)

Display image from url using holoviews

How can I display an image from url.
This result an error
import urllib
img = urllib.request.urlopen('https://www.edgystl.com/wp-content/uploads/2018/01/leather-bicker-jacket-model-street-style-men-1-e1530998880646.jpg')
hv.RGB(img)
HoloViews RGB elements expect generally expect a NumPy array, the easiest way of getting an array from an Image is to use the PIL (or Pillow) library and download it using requests. Here's what that looks like:
from PIL import Image
import requests
from io import BytesIO
url = 'https://www.edgystl.com/wp-content/uploads/2018/01/leather-bicker-jacket-model-street-style-men-1-e1530998880646.jpg'
response = requests.get(url)
img = Image.open(BytesIO(response.content))
hv.RGB(np.array(img))
Turns out it can be done with skimage
import holoviews as hv
from skimage import io
img = io.imread('https://www.edgystl.com/wp-content/uploads/2018/01/leather-bicker-jacket-model-street-style-men-1-e1530998880646.jpg')
hv.RGB(np.array(img))

Encode - decode base64 image

I have an image that is obtained from an OpenCV video capture object as such:
import cv2
import base64
from PIL import Image
import io
cap = cv2.VideoCapture(0)
# capture frame by frame
ret, frame = cap.read()
How can I encode and decode the image (i.e. go from raw pixels to bytes and back to raw pixels)?
So far I have been trying the following:
encoded_string = base64.b64encode(frame)
decoded_string = base64.b64decode(encoded_string)
img = Image.open(io.BytesIO(decoded_string))
img.show()
This is giving me an error:
File "/usr/lib/python3/dist-packages/PIL/Image.py", line 2295, in open
% (filename if filename else fp))
OSError: cannot identify image file <_io.BytesIO object at 0x7efddbb78e08>
The correct way of encoding and subsequently decoding an image with base64 turns out to be as follows:
import numpy as np
import cv2
import base64
cap = cv2.VideoCapture(0)
# capture frame by frame
ret, frame = cap.read()
# encode frame
encoded_string = base64.b64encode(frame)
# decode frame
decoded_string = base64.b64decode(encoded_string)
decoded_img = np.fromstring(decoded_string, dtype=np.uint8)
decoded_img = decoded_img.reshape(frame.shape)
# show decoded frame
cv2.imshow("decoded", decoded_img)

How to access images with plpython using the pillow libary and saving on postgresql bytea column?

I have a problem accessing an image procesed from database stored as a bytea here is my pl to resize an image.
CREATE OR REPLACE FUNCTION public.ajustar(randstring bytea)
RETURNS bytea
LANGUAGE plpythonu
AS $function$
from io import BytesIO
import PIL
from PIL import Image
basewidth = 300
mem_file = BytesIO()
mem_file.write(randstring)
img = Image.open(mem_file)
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize), PIL.Image.ANTIALIAS)
img.close()
return img
$function$;
So my problem is returning a bytea but get an adress, How I can get the image rather than the adress?. The only way it works is saving the img to a file with img.save('/home/postgres/imagen.jpg'), instead I need to put in a object to replace the image in the database.
pruebas=# select encode(ajustar(foto), 'escape') from personal where id=193;
encode
------------------------------------------------------------
<PIL.Image.Image image mode=RGB size=300x347 at 0x1895990>
(1 fila)
Thanks in advance
With this function you can process images on the database (jpeg format).
This are made with plpython and if you are using Linux update the pillow library on Centos 7 with
$sudo pip install Pillow
or
$sudo pip update Pillow
This is the function.
CREATE FUNCTION ajustar(randstring bytea) RETURNS bytea
LANGUAGE plpythonu
AS $$
from io import BytesIO
import PIL
from PIL import Image
basewidth = 300
mem_file = BytesIO()
mem_file.write(randstring)
img = Image.open(mem_file)
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize), PIL.Image.ANTIALIAS)
salida = BytesIO()
img.save(salida, format='JPEG')
hex_data = salida.getvalue()
img.close()
return hex_data
$$;

Resources