Wrong displayed image name in image viewer python 3.5 - python

When i open an image in image viewer the displayed image name is wrong (not the same as loaded image). Orginal image = 'image.PNG', name in image viewer='tmpy4uvijg0.BMP' (the new name always changeds, see in image below)
from PIL import Image
imName='image.PNG'
try:
with Image.open(imName) as im:
print(imName)
im.show()
except IOError:
pass
image.png
new image
What do i wrong? Why is the name not the same?

It is because the show method save the image to a temporary file, as say in the documentation:
Displays this image. This method is mainly intended for
debugging purposes.
On Unix platforms, this method saves the image to a temporary
PPM file, and calls the xv utility.
On Windows, it saves the image to a temporary BMP file, and uses
the standard BMP display utility to show it (usually Paint).
:param title: Optional title to use for the image window,
where possible.
:param command: command used to show the image
You can try to change the title by passing a string in parameter to show.

Related

Remove EXIF from Image Before Upload to S3 in Python

I want to remove exif from an image before uploading to s3. I found a similar question (here), but it saves as a new file (I don't want it). Then I found an another way (here), then I tried to implemented it, everything was ok when I tested it. But after I deployed to prod, some users reported they occasionally got a problem while uploading images with a size of 1 MB and above, so they must try it several times.
So, I just want to make sure is my code correct?, or maybe there is something I can improve.
from PIL import Image
# I got body from http Request
img = Image.open(body)
img_format = img.format
# Save it in-memory to remove EXIF
temp = io.BytesIO()
img.save(temp, format=img_format)
body = io.BytesIO(temp.getvalue())
# Upload to s3
s3_client.upload_fileobj(body, BUCKET_NAME, file_key)
*I'm still finding out if this issue is caused by other things.
You should be able to copy the pixel data and palette (if any) from an existing image to a new stripped image like this:
from PIL import Image
# Load existing image
existing = Image.open(...)
# Create new empty image, same size and mode
stripped = Image.new(existing.mode, existing.size)
# Copy pixels, but not metadata, across
stripped.putdata(existing.getdata())
# Copy palette across, if any
if 'P' in existing.mode: stripped.putpalette(existing.getpalette())
Note that this will strip ALL metadata from your image... EXIF, comments, IPTC, 8BIM, ICC colour profiles, dpi, copyright, whether it is progressive, whether it is animated.
Note also that it will write JPEG images with PIL's default quality of 75 when you save it, which may or may not be the same as your original image had - i.e. the size may change.
If the above stripping is excessive, you could just strip the EXIF like this:
from PIL import Image
im = Image.open(...)
# Strip just EXIF data
if 'exif' in im.info: del im.info['exif']
When saving, you could test if JPEG, and propagate the existing quality forward with:
im.save(..., quality='keep')
Note: If you want to verify what metadata is in any given image, before and after stripping, you can use exiftool or ImageMagick on macOS, Linux and Windows, as follows:
exiftool SOMEIMAGE.JPG
magick identify -verbose SOMEIMAGE.JPG

Opening an image with its original file name on display using Python?

I have a chart function that saves the end figure as a file. After I run the function, I also want it to display the figure at the end. So, I use this:
from PIL import Image
filepath = 'image.png'
img = Image.open(filepath)
img.show()
It works just fine, but when the file opens, it opens with a random file name, not the actual file name.
This can get troublesome as I have a lot of different chart functions that work in a similar fashion, so having logical names is a plus.
Is there a way I can open an image file with Python and have it display it's original file name?
EDIT
I'm using Windows, btw.
EDIT2
Updated the example with code that shows the same behaviour.
Instead of PIL you could use this:-
import os
filepath = "path"
os.startfile(filepath)
Using this method will open the file using system editor.
Or with PIL,
import Tkinter as tk
from PIL import Image, ImageTk # Place this at the end (to avoid any conflicts/errors)
window = tk.Tk()
#window.geometry("500x500") # (optional)
imagefile = {path_to_your_image_file}
img = ImageTk.PhotoImage(Image.open(imagefile))
lbl = tk.Label(window, image = img).pack()
window.mainloop()
The function img.show() opens a Windows utility to display the image. The image is first written to a temporary file before it is displayed. Here is the section from the PIL docs.
https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.show
Image.show(title=None, command=None)[source] Displays this image. This
method is mainly intended for debugging purposes.
This method calls PIL.ImageShow.show() internally. You can use
PIL.ImageShow.register() to override its default behaviour.
The image is first saved to a temporary file. By default, it will be
in PNG format.
On Unix, the image is then opened using the display, eog or xv
utility, depending on which one can be found.
On macOS, the image is opened with the native Preview application.
On Windows, the image is opened with the standard PNG display utility.
Parameters title – Optional title to use for the image window, where
possible.
"
The issue is that PIL uses a quick-and-dirty method for showing your image, and it's not intended for serious application use.

How do I save particular frames of video into folders using python?

I have got a code that does motion detection. It takes video as an input and then when an object comes to the scene, background changes and code publishes "object is seen" as text on that detected frame.
My question is that how do I save frames "when objects are seen" into folders( both for colorful and gray images)? I understand that I can write that frames using " cv2.imwrite("frame%d.jpg" % count, resizedFrame)" but unfortunately it does not work.
How do I save those detected frames to "colorful" and "gray" folders?
You have to read the image first by cv2.imread() and then cv2.imwrite()
here is a small example
import
cv2
# read image as grey scale
grey_img=cv2.imread('/home/img/python.png',cv2.IMREAD_GRAYSCALE)
# save image
status=cv2.imwrite('/home/img/python_grey.png',grey_img)
print("Image written to file-system : ",status)
If you're don't have the folder path then use this
status=cv2.imwrite('python_grey.png',grey_img)
it will save the photo in default folder in which you save your .py file
if you want to save different images here is the code
import cv2
import time
# for number of images you need different names so set name automatically
name=str(time.time())+str(.png))
# read image as grey scale
grey_img=cv2.imread('/home/img/python.png',cv2.IMREAD_GRAYSCALE)
# save image
status=cv2.imwrite('%s'%name,grey_img)
print("Image written to file-system : ",status)

Image does not change when adding an alpha channel

The pillow package has a method called Image.putalpha() which is used to add or change the alpha channel of an image.
I tried to play with this method and found that I can not change the background color of an image. The original image is
This is my code to add alpha to it
from PIL import Image
im_owl = Image.open("owl.jpg")
alpha = Image.new("L", im_owl.size, 50)
im_owl.putalpha(alpha)
im_owl.show()
The produced image is nothing different from the original image. I have tried with different value of alpha and see no difference.
What could have been wrong?
try to save the image and see it.
I am also not able to see the image directly from
im_owl.show()
but when I saved it
im_owl.save()
I am able to see the image changed.
Try using
im_owl.save("alphadOwl.png")
And then view the saved image. It would seem that the alpha channel isn't applied to bmp or jpg files. It is a bmp file that gets displayed with im.show()
(For the record, I'm on a mac, I don't know if im.show() uses different applications on other devices).
As #sanyam and #Pam have pointed out, we can save the converted image and it shows correctly. This is because on Windows, images are saved as temporary BMP file before they are shown using the system default image viewer, as per the PIL documentation:
Image.show(title=None, command=None)
Displays this image. This method is mainly intended for debugging purposes.
On Unix platforms, this method saves the image to a temporary PPM file, and calls
either the xv utility or the display utility, depending on which one can be found.
On macOS, this method saves the image to a temporary BMP file, and opens it with
the native Preview application.
On Windows, it saves the image to a temporary BMP file, and uses the standard BMP
display utility to show it (usually Paint).
To fix this issue, we can patch the Pillow code to use PNG format as default. First, we need to find the root of Pillow package:
import PIL
print(PIL.__path__)
On my system, the output is:
[’D:\Anaconda\lib\site-packages\PIL’]
Go to this directory and open the file ImageShow.py. I add the following code after the line register(WindowsViewer):
class WindowsPNGViewer(Viewer):
format = "PNG"
def get_command(self, file, **options):
return ('start "Pillow" /WAIT "%s" '
'&& ping -n 2 127.0.0.1 >NUL '
'&& del /f "%s"' % (file, file))
register(WindowsPNGViewer, -1)
After that, I can show the image with alpha channel correctly.
References
https://github.com/python-pillow/Pillow/issues/3695

why does resizing image in Pillow-python remove Image.format?

I'm resizing images in python using Pillow
image = Image.open("image_file.jpg")
print(image.format) # Prints JPEG
resized_image = image.resize([100,200],PIL.Image.ANTIALIAS)
print(resized_image.format) # Prints None!!
Why does resized_image.format Hold a None Value?
And How can i retain the format when resizing using pillow?
Because Image.resize creates a new Image object (resized copy of the image) and for any images when creating by the library itself (via a factory function, or by running a method on an existing image), the "format" attribute is set to None.
If you need the format attribute you still can to do this:
image = Image.open("image_file.jpg") #old image object
resized_image = image.resize([100,200],PIL.Image.ANTIALIAS)
resized_image.format = image.format # original image extension
Read the docs
As stated in the documentation:
The file format of the source file. For images created by the library itself (via a factory function, or by running a method on an existing image), this attribute is set to None.
You can specify the format on save:
image.save(fp, 'JPEG')
You can save the resized images with save comments
resized_image.save("New_image.png")
It will save into your current directory.
If you want to see in the python console itself you have to run
resized_image.show()

Categories