-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Image.open on Ubuntu 20.04 gives the error "No images found" in the viewer #5945
Comments
Why is the filename being written to the file? That was added in #3450 for the sake of security - so that nothing in the filename would be unintentionally interpreted as command line syntax. The A question - what viewer is being opened? |
Same
|
What image viewer is being opened? |
Ubuntu default image viewer eog, i even checked myself while keeping the viewer open |
It is calling xdg-open, which opens GNOME image viewer. The full error message is: |
ye i guess pillow deleting the file way more faster than it the viewer opening it. adding sleep might work. |
Thanks for testing that out. Would you be able to test out #5950 to see if that fixes the problem for you? |
Would be interesting to hear which image viewer is used in Pillow 8.4.0, before xdg-open was added in latest 9.0.0. I don't have Linux to test this, but one theory on what may be happening. Explicit image viewer
xdg-open
|
agreed |
This seems to solve the problem on my 20.04 test environment. |
@radarhere, I ran #5950 and it worked, but the program behavior has changed. It now opens the image using ImageMagick rather than using GNOME image viewer as before. It is no longer calling This might be masking the problem with |
Thanks for testing. @abarker if the image is still needed after we've finished calling |
this fix works for me too |
I'm not sure if the best place to discuss this is here or in the PR; after debugging this exact same issue I don't think this is the best approach. The issue is indeed that I think most users would expect and desire that the default image viewer application is prioritized for this usage. Ideally you would let the specific ordering be supplied as an optional argument and valid options would be attempted in the supplied order. In the (albeit somewhat unlikely event) that none of the other viewers are installed, users will still encounter completely broken behavior when I think the best solution here is to both introduce the same |
I'm experiencing the same error on "20.04.3 LTS (Focal Fossa)". The difference is that I'm trying to open a *.jpg file.
from PIL import Image
if __name__ == "__main__":
# open image
im = Image.open("images/vintage-cars.jpg")
# show image
im.show()
|
@alv2017 by default, Pillow will always attempt to show your image as a PNG. This isn't a bug, but a feature - just because Pillow supports an image format doesn't mean that the format would then be supported by a given image viewer. PNG is a common format that a given image viewer will be able to handle. Yes, JPEG is also common, but a line had to be drawn somewhere, this was simplest, and so you have it. If you would like to change the format that your image is shown in, >>> from PIL import Image, ImageShow
>>> for _viewer in ImageShow._viewers:
... _viewer.format = "JPEG"
...
>>> im = Image.new("RGB", (100, 100))
>>> im.show() If you disagree with my reasoning, please create a new issue about that specifically, to keep this thread neat. |
@radarhere thanks for the answer, |
So, I've just run into this issue after upgrading to Pillow 9.0.0 from 8.1.2. I use KDE and the default viewer with |
This should now be resolved in Pillow 9.0.1. Let us know if you are still experiencing a problem. @modwizcode @abarker this was fixed by adding a delay after all, so @BrettRyland I'd like to relocate discussion of your comment to #5976 if you don't mind |
Hi, sorry but this needs re-opening as the "fix" doesn't work. You need to monitor the process and only remove the file once the process using it closes. After the 20s delay runs out, the image is removed and the viewer (gwenview in this case) automatically updates to account for the image disappearing. |
Since you appear to be using |
Would it be a bad idea to stop auto-deleting temporary files and leave it to the operating system or Pillow user to take care of it? Windows apparently doesn't clear the https://superuser.com/a/296827/83235 macOS: https://superuser.com/a/187105/83235 Linux: old answers but it varies from boot to a number of hours. |
Based on this stackoverflow post, it's possible to query which command would be run by import os
import subprocess
from xdg import BaseDirectory, DesktopEntry
def xdg_query(command, parameter):
p = subprocess.Popen(
["xdg-mime", "query", command, parameter],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
output, errors = p.communicate()
if p.returncode or errors:
raise XDGError(
"xdg-mime returned error code %d: %s" % (p.returncode, errors.strip())
)
return output.strip()
desktop_filename = xdg_query('default', 'image/png')
res = BaseDirectory.load_data_paths('applications', desktop_filename.decode())
desktop_file = next(res) if res else None
entry = DesktopEntry.DesktopEntry(desktop_file) if desktop_file is not None and os.path.exists(desktop_file) else None
image_filename = 'repos/arctic-ice/data/unmarked/20190831-flight1_transparent_mosaic_group1.tif'
p = subprocess.Popen([entry.getExec().split(' ')[0],image_filename])
p.wait() (Sorry the code's a bit messy, I was just getting it to work in the Edit: Also, the |
https://github.com/alv2017/Pillow/tree/test_unix_viewers please have a look (I have activated the workflows) The solution is user-oriented, i.e. if the user created a Python program that shows the images, |
@radarhere, @hugovk I noticed that this error is repeatedly showing up: ================================== FAILURES ===================================
_________________________________ test_sanity _________________________________
tmp_path = WindowsPath('C:/Users/runneradmin/AppData/Local/Temp/pytest-of-runneradmin/pytest-0/test_sanity8')
@pytest.mark.skipif(not ImageQt.qt_is_installed, reason="Qt bindings are not installed")
def test_sanity(tmp_path):
# Segfault test
app = QApplication([])
ex = Example()
assert app # Silence warning
assert ex # Silence warning
for mode in ("1", "RGB", "RGBA", "L", "P"):
# to QPixmap
im = hopper(mode)
data = ImageQt.toqpixmap(im)
assert isinstance(data, QPixmap)
assert not data.isNull()
# Test saving the file
tempfile = str(tmp_path / f"temp_{mode}.png")
data.save(tempfile)
# Render the image
qimage = ImageQt.ImageQt(im)
data = QPixmap.fromImage(qimage)
qt_format = QImage.Format if ImageQt.qt_version == "6" else QImage
qimage = QImage(128, 128, qt_format.Format_ARGB32)
painter = QPainter(qimage)
image_label = QLabel()
image_label.setPixmap(data)
image_label.render(painter, QPoint(0, 0), QRegion(0, 0, 128, 128))
painter.end()
rendered_tempfile = str(tmp_path / f"temp_rendered_{mode}.png")
qimage.save(rendered_tempfile)
assert_image_equal_tofile(im.convert("RGBA"), rendered_tempfile)
# from QPixmap
> roundtrip(hopper(mode))
Tests/test_qt_image_qapplication.py:85:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Tests/test_qt_image_qapplication.py:47: in roundtrip
assert_image_equal(result, expected.convert("RGB"))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
a = <PIL.PpmImagePlugin.PpmImageFile image mode=RGB size=128x128 at 0x23980B9D790>
b = <PIL.Image.Image image mode=RGB size=128x128 at 0x23980B9D7F0>, msg = None
def assert_image_equal(a, b, msg=None):
assert a.mode == b.mode, msg or f"got mode {repr(a.mode)}, expected {repr(b.mode)}"
assert a.size == b.size, msg or f"got size {repr(a.size)}, expected {repr(b.size)}"
if a.tobytes() != b.tobytes():
if HAS_UPLOADER:
try:
url = test_image_results.upload(a, b)
logger.error(f"Url for test images: {url}")
except Exception:
pass
> assert False, msg or "got different content"
E AssertionError: got different content
E assert False
Tests/helper.py:98: AssertionError
------------------------------ Captured log call ------------------------------
ERROR Tests.helper:helper.py:94 Url for test images: D:/a/Pillow/Pillow/Tests/errors/tmplryrz69l |
Yep, one or two of the Qt tests are a bit flaky, we should consider something to rerun those (maybe with a https://pypi.org/project/flaky/ decorator) or perhaps even skip them on MinGW. (Or figure out the root cause and fix that...) |
@hugovk this error shows up when: 1) a.mode == b.mode; 2) a.size == b.size; 3) a.tobytes() != b.tobytes(); |
@radarhere, @hugovk another problem I face (it is showing up from time to time on Windows setups):
|
Does not seem to be a Pillow issue, also reported here: actions/runner-images#5009 |
Well it seems 9.0.1 still have some bugs now the show command is working but it is not terminating the shell after closing the file viewer while 8.4.0 working so well. |
@alv2017 this should now been fixed |
@MayankFawkes that's interesting. What file viewer are you using? |
#6045 has now been merged, so in the next release of Pillow, temporary image files will no longer be removed on Unix. @BrettRyland are you ok for this to be resolved? |
It resolves the issue, but I would still prefer to be able to easily configure which viewer to be used instead of relying on the system default for opening image files as I think there is a significant difference in the purpose of an image viewer vs an image editor or gallery viewer and the system default does not provide a distinction between these. |
Closing. The discussion about selecting the viewer can be continued in #5976 |
FWIW I just ran into this on Windows 10 after installing a new image editor. The first time I used |
I know this is closed, but another "good" solution would be to delete the temporary image file when the image shown is garbage collected. And yet another would be to delete it when the interpreter shutsdown. |
The viewer is opened, but a "No images found" error is displayed. Pillow version
pillow-9.0.0
. This may be the same bug: https://stackoverflow.com/questions/63579415/why-does-pil-fail-to-display-images-with-error-no-images-found-in-file-tmpCode to reproduce:
Changing the code in the
UnixViewer
class inImageShow.py
seems to fix it. I'm not sure why the current code is writing the filename to a file and then reading it back from stdin, usingshell=True
inPopen
. Deleting therm -f $im"
command in thePopen
call seems to fix the problem. It also seems to work usingcat | xargs -L1
in the Popen command instead of setting the shell variableim
.This simpler code replacement also seems to work, without setting
shell=True
:The text was updated successfully, but these errors were encountered: