Writing image into a PDF File - python-3.x

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, ...)

Related

How to save "IPython.core.display.SVG" as PNG file?

I am trying to save a variable with data-type of "IPython.core.display.SVG" as a PNG file in Jupyter Notebook environment.
First I tried:
with open('./file.png','wb+') as outfile:
outfile.write(my_svg.data)
And I got the error:
TypeError: a bytes-like object is required, not 'str'
Next, I tried:
with open('./file.png','wb+') as outfile:
outfile.write(my_svg.data.encode('utf-8'))
But, I cannot open "file.png". The operating system gives error:
The file “file.png” could not be opened. It may be damaged or use a file format that Preview doesn’t recognize.
I can save "my_svg" with "svg" extension as below:
with open('./file.svg','wb+') as outfile:
outfile.write(my_svg.data.encode('utf-8'))
But, when I want to convert "file.svg" into "file.png" by:
import cairosvg
cairosvg.svg2png(url="./file.svg", write_to="./file.png")
I get the error:
ValueError: unknown locale: UTF-8
This is how I get "IPython.core.display.SVG" data-type in Jupyter Notebook:
from rdkit import Chem
from rdkit.Chem.Draw import rdMolDraw2D
from IPython.display import SVG
smile_1 = 'C(C(N)=O)c(c)c'
smile_2 = 'o(cn)c(c)c'
m1 = Chem.MolFromSmiles(smile_1,sanitize=False)
Chem.SanitizeMol(m1, sanitizeOps=(Chem.SanitizeFlags.SANITIZE_ALL^Chem.SanitizeFlags.SANITIZE_KEKULIZE^Chem.SanitizeFlags.SANITIZE_SETAROMATICITY))
m2 = Chem.MolFromSmiles(smile_2,sanitize=False)
Chem.SanitizeMol(m2, sanitizeOps=(Chem.SanitizeFlags.SANITIZE_ALL^Chem.SanitizeFlags.SANITIZE_KEKULIZE^Chem.SanitizeFlags.SANITIZE_SETAROMATICITY))
mols = [m1, m2]
legends = ["smile_1", "smile_2"]
molsPerRow=2
subImgSize=(200, 200)
nRows = len(mols) // molsPerRow
if len(mols) % molsPerRow:
nRows += 1
fullSize = (molsPerRow * subImgSize[0], nRows * subImgSize[1])
d2d = rdMolDraw2D.MolDraw2DSVG(fullSize[0], fullSize[1], subImgSize[0], subImgSize[1])
d2d.drawOptions().prepareMolsBeforeDrawing=False
d2d.DrawMolecules(list(mols), legends=legends)
d2d.FinishDrawing()
SVG(d2d.GetDrawingText())
Environment:
macOS 11.2.3
python 3.6
RDKit version 2020.09.1
Any help is greatly appreciated.
Instead of creating an SVG with rdkit and trying to convert it to a PNG, why not just create a PNG directly?
from rdkit.Chem import Draw
from rdkit import Chem
# create rdkit mol
smile = 'CCCC'
mol = Chem.MolFromSmiles(smile)
# create png
d2d = Draw.MolDraw2DCairo(200, 200)
d2d.DrawMolecule(mol)
d2d.FinishDrawing()
png_data = d2d.GetDrawingText()
# save png to file
with open('mol_image.png', 'wb') as png_file:
png_file.write(png_data)
I am not sure why MolDraw2DCairo is not working for you but using the package you mention (cairosvg) you could extend your code sample quite easily:
# extra imports
import cairosvg
import tempfile
# replace molecule drawing part
d2d = rdMolDraw2D.MolDraw2DSVG(fullSize[0], fullSize[1], subImgSize[0], subImgSize[1])
d2d.drawOptions().prepareMolsBeforeDrawing=False
d2d.DrawMolecules(list(mols), legends=legends)
d2d.FinishDrawing()
svg_text = d2d.GetDrawingText()
# save to png file
with tempfile.NamedTemporaryFile(delete=True) as tmp:
tmp.write(svg_text.encode())
tmp.flush()
cairosvg.svg2png(url=tmp.name, write_to="./mol_img.png")

Decompress nifti medical image in gz format using python

I want to decompress a butch of nii.gz files in python so that they could be processed in sitk later on. When I decompress a single file manually by right-clicking the file and choosing 'Extract..', this file is then correctly interpreted by sitk (I do sitk.ReadImage(unzipped)). But when I try to decompress it in python using following code:
with gzip.open(segmentation_zipped, "rb") as f:
bindata = f.read()
segmentation_unzipped = os.path.join(segmentation_zipped.replace(".gz", ""))
with gzip.open(segmentation_unzipped, "wb") as f:
f.write(bindata)
I get error when sitk tries to read the file:
RuntimeError: Exception thrown in SimpleITK ReadImage: C:\d\VS14-Win64-pkg\SimpleITK\Code\IO\src\sitkImageReaderBase.cxx:82:
sitk::ERROR: Unable to determine ImageIO reader for "E:\BraTS19_2013_10_1_seg.nii"
Also when trying to do it a little differently:
input = gzip.GzipFile(segmentation_zipped, 'rb')
s = input.read()
input.close()
segmentation_unzipped = os.path.join(segmentation_zipped.replace(".gz", ""))
output = open(segmentation_unzipped, 'wb')
output.write(s)
output.close()
I get:
RuntimeError: Exception thrown in SimpleITK ReadImage: C:\d\VS14-Win64-pkg\SimpleITK-build\ITK\Modules\IO\PNG\src\itkPNGImageIO.cxx:101:
itk::ERROR: PNGImageIO(0000022E3AF2C0C0): PNGImageIO failed to read header for file:
Reason: fread read only 0 instead of 8
can anyone help?
No need to unzip the Nifti images, libraries such as Nibabel can handle it without decompression.
#==================================
import nibabel as nib
import numpy as np
import matplotlib.pyplot as plt
#==================================
# load image (4D) [X,Y,Z_slice,time]
nii_img = nib.load('path_to_file.nii.gz')
nii_data = nii_img.get_fdata()
fig, ax = plt.subplots(number_of_frames, number_of_slices,constrained_layout=True)
fig.canvas.set_window_title('4D Nifti Image')
fig.suptitle('4D_Nifti 10 slices 30 time Frames', fontsize=16)
#-------------------------------------------------------------------------------
mng = plt.get_current_fig_manager()
mng.full_screen_toggle()
for slice in range(number_of_slices):
# if your data in 4D, otherwise remove this loop
for frame in range(number_of_frames):
ax[frame, slice].imshow(nii_data[:,:,slice,frame],cmap='gray', interpolation=None)
ax[frame, slice].set_title("layer {} / frame {}".format(slice, frame))
ax[frame, slice].axis('off')
plt.show()
Or you can Use SimpleITK as following:
import SimpleITK as sitk
import numpy as np
# A path to a T1-weighted brain .nii image:
t1_fn = 'path_to_file.nii'
# Read the .nii image containing the volume with SimpleITK:
sitk_t1 = sitk.ReadImage(t1_fn)
# and access the numpy array:
t1 = sitk.GetArrayFromImage(sitk_t1)

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

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)

Load datasets and store it in another file using opencv

How can I read all images from datasets and store it in another location using opencv.
You can use glob to read the files in a folder.
import glob
import cv2
for file in glob.glob('source/*.png'):
img = cv2.imread(file)
filename = 'destination/'+file.split('source\\')[1]
cv2.imwrite(filename, img)
Split function of python can be used to obtain the image-name which is then written to the destination folder.
NOTE- If the folders are not in the current working directory please specify the absolute path. For more on absolute and relative paths refer here.
import os
import cv2
SOURCE_FOLDER = "a"
DESTINATION_FOLDER = "b"
for image_file_name in os.listdir(SOURCE_FOLDER):
# get full path to image file
image_path = os.path.join(SOURCE_FOLDER, image_file_name)
# read image
img = cv2.imread(image_path)
# store image in another folder
image_write_path = os.path.join(DESTINATION_FOLDER, image_file_name)
cv2.imwrite(image_write_path, img)

How to load images from Google Cloud Storage with keras.preprocessing

I am writing machine learning code that can be trained locally or in the cloud. I am using keras.preprocessing to load images, which under the hood uses PIL. It works fine for local files, but understandably doesn't understand Google Cloud Storage paths, like "gs://...".
from keras.preprocessing import image
image.load_img("gs://myapp-some-bucket/123.png")
Gives this error:
.../lib/python2.7/site-packages/keras/preprocessing/image.py", line 320, in load_img img = pil_image.open(path) File
.../lib/python2.7/site-packages/PIL/Image.py", line 2530, in open fp = builtins.open(filename, "rb") IOError: [Errno 2] No such file or directory: 'gs://myapp-some-bucket/123.png'
What is the correct way of doing this? I ultimately need a folder of images to be a single numpy array (images decoded and grayscale).
Found a replacement for keras.preprocessing.image.load_img, that understands GCS. I also included more code to read the whole folder, and turn every image in the folder into a single numpy array for training...
import os
import tensorflow as tf
from tensorflow.python.platform import gfile
filelist = gfile.ListDirectory("gs://myapp-some-bucket")
sess = tf.Session()
with sess.as_default():
x = np.array([np.array(tf.image.decode_png(tf.read_file(os.path.join(train_files_dir, filename))).eval()) for filename in filelist])
Load image:
image_path = 'gs://xxxxxxx.jpg'
image = tf.read_file(image_path)
image = tf.image.decode_jpeg(image)
image_array = sess.run(image)
Save image:
job_dir = 'gs://xxxxxxxx'
image = tf.image.encode_jpeg(image_array)
file_name = 'xxx.jpg'
write_op = tf.write_file(os.path.join(job_dir, file_name), image)
sess.run(write_op)

Resources