can't save the image after using PIL Image.thumbnail - python

I am quite confused cause when I try to save the resized version of an image it says 'AttributeError: 'NoneType' object has no attribute 'save''.
I looked over the internet and also to this question: Python Pillow's thumbnail method returning None but i already used the save function so i don't get why it doesn't work.
Here's my code:
from PIL import Image
imgg = Image.open('cropped.tif')
new_image = imgg.thumbnail((400, 400))
new_image.save('thumbnail_400.tif')
I bet it's something stupid but i can't see what it is. I appreciate any help.

thumbnail() is an extension method without a return object. The new_image variable will stay None in your case. You need to do this.
from PIL import Image
imgg = Image.open('cropped.tif')
imgg.thumbnail((400, 400))
imgg.save('thumbnail_400.tif')

Related

cv2.error: OpenCV(4.5.2) .error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'

import cv2 #for image processing
import easygui #to open the filebox
import numpy as np #to store image
import imageio #to read image stored at particular path
import sys
import matplotlib.pyplot as plt
import os
import tkinter as tk
from tkinter import filedialog
from tkinter import *
from PIL import ImageTk, Image
top=tk.Tk()
top.geometry('400x400')
top.title('Cartoonify Your Image !')
top.configure(background='white')
label=Label(top,background='#CDCDCD', font=('calibri',20,'bold'))
def upload():
ImagePath=easygui.fileopenbox()
cartoonify(ImagePath)
def cartoonify(ImagePath):
# read the image
originalmage = cv2.imread(ImagePath)
originalmage = cv2.cvtColor(originalmage, cv2.COLOR_BGR2RGB)
#print(image) # image is stored in form of numbers
cv2.error: OpenCV(4.5.2) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-vi271kac\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'
Check the image address again. This usually happens when the image is not loaded correctly in any way. Try giving the address directly; something like "C:\\test.jpg"
import cv2
im = cv2.imread("WRONG IMAGE ADDRESS.jpg", 1)
im = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
Update
You can also get the current folder path of your script and load your image from that.
Imagine your files structure are like this:
--RootProject
|-img.jpg
|-script.py
Then you can also do something like this:
script.py
import cv2
import sys
im = cv2.imread(sys.path[0]+"/img.jpg", 1)
im = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
Try giving the image as a path, and one thing to be careful is about the slashes. Use \\ instead of \. Your path must look like D:\\file\\file1\\file2.
To check if it worker print type(cv2.imread(path)). If it prints <class 'numpy.ndarray'>, then you are good to go.
This may happen if your image file path is wrong, add your working folder then use as below:
image = cv2.imread('eye_face.jpg')
type(image)
then your image type will indicate as numpy.ndarray, if your image file path is wrong then the type will be NoneType.
This error is {wrong image location}. If suppose your image in another folder means use like this:
img=cv2.imread("../images/car.jpg",1)
This seems to be the path issue in windows. I changed it to a full path like this and it worked.
filename = "D:\Sandbox\Github\opencv-project\Resources\Photos\cats.jpg"
I was trying to read images from a folder and having the same trouble. I had a non-image in one of the folders that was the problem.
I solved the same problem by adding:
data = cv2.imread('path_to_your_image', as_grey =True)
and then try to also add the flags = cv2.DFT_COMPLEX_OUTPUT to this line
dft = cv2.dft(np.float32('your_image'),flags = cv2.DFT_COMPLEX_OUTPUT)
there are many solutions for this issue out there.
This might be because of your camera issue or the camera driver issue. If you are using any USB camera then cross-check its connection and ensure that no other programs are using the same camera.
If your camera is working then you might put the wrong image path. Verify the image path. Also, try to put a hardcoded path like C:\\image1.png if needed.
import cv2
im = cv2.imread("C:\\image1.png", 1)
im = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
Please check the extension you give to the path. JPEG,PNG or anything else.
Check if your camera has been disabled in the device manager, or else upadate it.

NoneType' object is not subscriptable

Getting the error bellow in the code
TypeError: 'NoneType' object is not subscriptable
line : crop_img = img[70:300, 70:300]
Can anyone please help me with this?
thanks a lot
img_dofh = cv2.imread("D.png",0)
ret, img = cap.read()
cv2.rectangle(img,(60,60),(300,300),(255,255,2),4) #outer most rectangle
crop_img = img[70:300, 70:300]
crop_img_2 = img[70:300, 70:300]
grey = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY)
You don't show where your img variable comes from. But somehow it is None instead of containing image data.
Often this happens when you write a function that is supposed to return a valid object for img, but you forget to include a return statement in the function, so it automatically returns None instead.
Check the code that creates img.
UPDATE
Responding to your code posting:
It would be helpful if you could provide a minimal, reproducible example. That might look something like this:
import cv2
cap = cv2.VideoCapture(0)
if cap.isOpened():
ret, img = cap.read()
if img is None:
print("img was not returned.")
else:
crop_img = img[70:300, 70:300]
print(crop_img) # should show an array of image data
Looking at the documentation, it appears that your camera may not have grabbed any frames by the time you reach this point in your code. The documentation says "If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer." I would bet that the .read() function is returning a NULL pointer, which gets converted to None when it is sent back to Python.
Unfortunately, since no one else has your particular camera setup, other people may have trouble reproducing your problem.
The code above works fine on my MacBook Pro, but I have to give Terminal permission to use the camera the first time I try it. Have you tried restarting your terminal app? Does your program have access to the camera?

PIL - image.open returning wrong type

I'm using PIL's image library to handle JPG files. From my understanding, calling PIL's open() function should return an object of type Image. However I'm having a problem where it returns an object of type PIL.JpegImagePlugin.JpegImageFile. Here's the code I'm running:
from PIL import Image
for filename in os.listdir(""):
new_filename = filename
if(filename[0] == '.'):
new_filename = filename[2:]
picture = Image.open(new_filename, 'r')
print(type(picture))
Can somebody tell me how to fix this?
According to the documentation, the PIL.JpegImagePlugin.JpegImageFile class is a subclass of the PIL.Image.Image class.
So your object is a specific kind of Image and can be used as an Image =).

Python Image object to WxPython

I just want to display python image object in wxpython panel.
What i am trying to accomplish is taking screenshot using python ImageGrab or autopy and showing it in wxpython panel. My screenshot program running every second so there is no point save the image for wx.
import pyscreenshot as ImageGrab
imgobj = ImageGrab.grab()
print imgobj
# Convert into wximage
myWxImage = wx.EmptyImage( imgobj.size[0], imgobj.size[0] )
myWxImage.SetData( imgobj.convert( 'RGB' ).tostring())
Output
<Image.Image image mode=RGB size=1366x768 at 0x20B98F0>
ValueError:Invalid data buffer size.
It's not easy to tell without a full traceback, but I think the issue might be this typo:
myWxImage = wx.EmptyImage( imgobj.size[0], imgobj.size[0] )
Should be:
myWxImage = wx.EmptyImage( imgobj.size[0], imgobj.size[1] )
Also you could make your code simpler with:
myWxImage = wx.ImageFromBuffer(imgobj.size[0], imgobj.size[1], imgobj.convert('RGB').tostring())
I assume your problem is that you are passing the image width as new height to wx...
And btw instead you could use
myWxImage = wx.ImageFromBuffer( imgobj.size[0], imgobj.size[1], imgobj.tostring() )

ReportLab and Python Imaging Library images from memory issue

I've run into an issue I can't seem to figure out with PIL and reportlab. Specifically, I would like to use drawImage on a canvas in reportlab using a PIL Image object.
In the past I've inserted images into reportlab documents from the web using raw data, StringIO and reportlab's ImageReader class. Unfortunately, ImageReader takes a file name or a file buffer like object.
The ultimate goal is to be able to put QR codes, (which are PIL objects) into the reportlab PDFs. One thing that does work is the following:
size, qrcode = PyQrcodec.encode('http://www.google.com')
qrcode.save("img.jpeg")
self.pdf.drawImage(ImageReader("img.jpeg"), 25, 25, width=125, height=125)
self.pdf.showPage()
This saves the image and then reads it into the pdf. Obviously doing it like this doesn't make sense.
My efforts are compounded by the relatively long development history of reportlab which makes finding the answers relevant to the latest version (2.4).
Thanks for the help.
(By the way, I'm using 1.1.6 PIL)
Although it does look like it should work, it really doesn't. I finally was able to track down the problem, and it was in the _isPILImage() function. The problem is that "Image.Image" is actually "from PIL import Image" whereas my object is actually just from Image. I would have assumed they were the same, but in any case isinstance doesn't evaluate them as the same. My hack solution was to change _isPILImage(fileName): ... to
519 def _isPILImage(im):
520 import Image as PIL_Image
521 try:
522 return isinstance(im,Image.Image) or isinstance(im, PIL_Image.Image)
523 except ImportError:
524 return 0
That solves my error. Since you pointed me in the right direction I originally tried to post this as a comment then accept your answer, but it doesn't allow enough characters.
Thank you for the input! If you can think of a more elegant way to fix this... (I tried to wrap the Image.Image object in a PIL Image object) let me know!
Looking at the source for ReportLab 2.4, it seems that ImageReader will accept a PIL Image object as "filename".
def _isPILImage(im):
try:
return isinstance(im,Image.Image)
except ImportError:
return 0
class ImageReader(object):
"Wraps up either PIL or Java to get data from bitmaps"
_cache={}
def __init__(self, fileName):
if isinstance(fileName,ImageReader):
self.__dict__ = fileName.__dict__ #borgize
return
#start wih lots of null private fields, to be populated by
#the relevant engine.
self.fileName = fileName
self._image = None
self._width = None
self._height = None
self._transparent = None
self._data = None
if _isPILImage(fileName):
self._image = fileName
self.fp = getattr(fileName,'fp',None)
try:
self.fileName = self._image.fileName
except AttributeError:
self.fileName = 'PILIMAGE_%d' % id(self)
weired
the documentation claims that drawImage and drawInlineImage work the same way, but it works with drawInlineImage out of the box, and do not work in drawImage
This is what I did, using plotly, BytesIO and reportlab. It puts an image in the pdf from memory, without having to save it on disk first.
import io
import plotly.graph_objects as go
from reportlab.platypus import SimpleDocTemplate, Image
image_in_memory = io.BytesIO()
figure = go.Figure(data=data) # as it's not part of the question I'm leaving data out
figure.write_image(image_in_memory, scale=5, width=1000, height=400)
pdf_image = Image(image_in_memory, width=400, height=160)
pdf_document = SimpleDocTemplate(path, title='Title')
pdf_document.multiBuild([pdf_image])

Categories

Resources