Screenshots are copied as .png

Hello,

I have noticed that screenshots are copied as .png, even though the images are saved locally as .jpeg, if selected in “Image Saving”.

This poses issues with e.g. chat clients which limit the upload size.
It also takes longer to send, due to their size or how images are treated by the client in which they are being processed.

They do save as .jpeg in the selected path though, so it is not like the function is working incorrectly.

The current solution for me is right clicking the notification of the saved screenshot and selecting “Copy”. This copies the saved file, which is indeed .jpeg.

Best regards,

Nyun

As I was too slow to edit, I will just reply to myself:

I think the dropdown in “General > After taking a screenshot” should include “copy file to clipboard”.

This ensures that people who want the .png in their clipboard still have that behavior and those who don’t, can choose to use the saved file instead.

You actually can paste JPEG from Spectacle, but many apps including popular apps like Chromium, Firefox and Discord only support pasting PNG. Spectacle forces your preferred format to the top of the list of pasteable formats when you copy an image, but what you actually get when you paste can be hard to predict because it depends on what other apps support and even how the desktop environment handles clipboard contents after the app that copied to the clipboard closes. Before clipboard managers were invented, your clipboard contents would just disappear when you closed the copying app. For text, storing the copied data in a clipboard manager is no big deal, but for large, complicated and diverse formats like images, it’s hard to be totally certain that you’ll get exactly what you copied when you paste.

Here’s an example of all the formats that can be pasted when you copy an image from spectacle with JPEG as your preferred format:

image/jpeg
application/x-qt-image
x-kde-force-image-copy
application/x-kde-suggestedfilename
image/png
image/avif
image/bmp
image/bw
image/cur
image/dds
image/eps
image/epsf
image/epsi
image/exr
image/hej2
image/icns
image/ico
image/j2k
image/jfif
image/jp2
image/jpg
image/jxl
image/pbm
image/pcx
image/pgm
image/pic
image/ppm
image/qoi
image/rgb
image/rgba
image/sgi
image/tga
image/tif
image/tiff
image/wbmp
image/webp
image/xbm
image/xpm
1 Like

That is a bit strange.

Usually copying an image to clipboard using Qt’s clipboard API would create an offer for all image formats Qt supports, leaving it to the target to select the one it likes most.

After a quick look into Spectacle’s sources it seems it is using some custom code and choosing the format preferred for saving.

Neither seems to be what you are experiencing.

Edit: ah, if I understand @ndavis post correctly then Spectacle is actually doing both of these approaches combined :slight_smile:

I should note that apps frequently support pasting image files in various formats, but pasting raw image data is another thing. I could make it so that when you click Copy Image you copy an temporary image file with the format you want, but there’s no guarantee that an app will actually paste the contents of the file provided. For instance, some apps may handle pasting an image file as just pasting the text file://temp/myimage.jpeg instead of actually pasting your image. I’ve never seen one do that, but some apps like Discord won’t copy temp files when in a Flatpak.

I am not sure I can follow, but as I understood it, copying the raw image file converted as jpeg and pasting it, is something that can go haywire in apps like Discord?

Copying the file, as I proposed, worked without issues on my end. After thinking more about it, I noticed that this can only work for people that do save their images, though.

To reduce the risk of issues, is there a way to instead compress the image before transmitting it into the clipboard? That might also work, now that I think about it.

The only issues I currently have with the way it is now, is that e.g. discord may cry about the file size or may not fully load the clipboard content (possibly also due to size?) and fails to send the image. (this happens regularly with 1440p full screenshots)

If the latter happens, I either have to repaste (rarely works), recapture (whyever that works) or send the file instead. (hence my suggestion)

Not exactly haywire. If the pasting app (e.g., Discord) supports pasting raw JPEG data, then it will paste in the JPEG format as expected. If the pasting app does not support pasting raw JPEG data and the copying app (e.g., Spectacle) doesn’t provide a way to get a supported format (e.g., PNG), then nothing will happen when you try to paste. It’s just confusing when you don’t know about these details and disappointing when you do.

Copying the file, as I proposed, worked without issues on my end. After thinking more about it, I noticed that this can only work for people that do save their images, though.

Yes, it works for a lot of apps because they have logic in them to handle pasted URLs with a file scheme (e.g., file:///tmp/image.png). This common because it’s just good app design, but there’s no guarantee that they will do it. Sometimes apps might only accept raw image data if they’re very basic. Sometimes apps in a Flatpak aren’t allowed to touch certain locations like /tmp. Even if the copying app saves a temporary image file in your preferred format and copies the local file URL (e.g., file:///tmp/image.jpeg) as a workaround, there’s no guarantee it’ll work as expected for apps that can normally paste local file URLs. Because of that, we need a dedicated action for copying raw image data. That’s what the Copy Image button/shortcut is for.

NGL, I thought copying and pasting was a solved problem before I had to deal with this. It’s something that seems basic and old, but it still has a number of quirks.

Sorry, I missed this. I suppose it could make sense. It’s going to be annoying to explain the difference between copying the raw data and copying the file in the UI though. It might also mean we should try to come up with a solution in another way.

If the above is possible, I think that this may also prove to be a good solution, as it may solve the issues I, and possibly others, experience, too:

Fullscreen Screenshots in Discord

  • sometimes only 1/3 of the image is shown in the preview; upload fails afterwards

  • same as above, but while it may have worked in one chat, it may not work in another chat (which is just weird)

  • sometimes the image is just too big, especially screenshots from Games in 1440p or bigger

Fullscreen Screenshots in Telegram or others

  • images take long to load in the app itself, but at least rarely fail

I do think that the incomplete upload issue in discord may have something to do with how Wayland works (correct me if wrong), possibly because of what you explained earlier?
At least I recall reading about a similar issue some months ago in conjunction with Wayland.

That is already the case if the chosen format has compression.

Different image formats use different types of compression, e.g. JPEG uses a “lossy” compression and can usually reduce data size more than PNG which uses traditional compression.

Copy & paste works essentially like this:

  1. the source application creates announces it has data available in any number of formats
  2. the target application chooses one of the formats and asks for the data
  3. the source application sends the data in the chosen format
  4. the target application receives the data in the chosen format

If the source application exits before step 2, then the clipboard manager will try to get and store the data, usually in the first format offered. It then becomes the new source application but with a reduced offer of formats.

If you look at the list of formats offered by Spectacle in step 1, it has some which have compression and some which don’t.
So whether the data transferred between the two applications is compressed mostly depends on the choice of the target application.

If the source offers JPEG as an option and the target chooses JPEG it will receive JPEG data.

I wonder if there is some Qt logging that would tell us which format has been chose, or some sort of test “source” application which would log that.

This is another very enlightening topic. I did some tests by telling spectacle to save as very low quality jpeg (to make it easier to discern) and Dolphin is the only application that actually lets me save the jpeg. Every other application I tested opted to take the png version instead: Gimp, Inkscape, Krita, LibreOffice, OnlyOffice, Firefox, Thunderbird, Chromium, Mattermost, Slack.

I was going to suggest adding a help text to spectacles’ image saving settings to explain how this setting can also influence pasted content, but as things stand this would probably only confuse.

Since it doesn’t actually do anything with the data it will likely just take the first offer.
Which will be JPEG if that is what the user of Spectacle has set as their preferred format.

Which also makes sense.

PNG is a loss-less compressed format, so you are not risking any quality loss during copy & paste. JPEG works well for photo-like images but can create bad artifacts for drawing-like ones.

And the target application can still apply its own format conversion, compression or quality level change.

GIMP, for example, would want to have the best quality data possible.

I more or less meant increasing the compression of the .png, not into another container.

From my understanding now, in Step 3, Spectacle converts the raw data into a .png (or whatever the application asks for) and pastes that into the target application.

So, from what I gathered, this convert takes some time.
This explains the delay in Telegram for full size images and this may also be the reason why sometimes Discord only sees 1/3 of the image, as it takes some time to convert.

As of now I see that there are two separate issues with the way it is now:

  1. Conversion takes too long, so target applications may show signs of corruption (Discord) or slow loading times when pasting (Telegram)
  2. Conversion into .png (as requested by most applications) results in high file sizes, which may be mitigated with higher compression rates (if applicable)

If it helps I can provide a video which shows both of these issues fairly clearly.

Also, is it possible issue #1 is due to some failure with NVIDIA drivers/hardware acceleration not doing what it is supposed to do?
Maybe, if hardware acceleration is not in this equation, the CPU not being used “in an optimal way”, e.g. not doing parallel jobs or similar.
(Please do not behead me, if what I am suggesting makes no sense. I only have surface level of knowledge about things like these)

Yes, that is roughly correct :slight_smile:

True, however it is probably just a matter of milliseconds.

I wonder if the bottleneck is the data transfer, not as much the encoding and decoding on each end.

Not easy to measure due to many processes being involved.

PNG compression is usually relatively fast on modern computers, but on higher compression levels it can take a few seconds with 4K images, especially game screenshots (which would compress better as jpegs in most cases). With Full-HD size images it shouldn’t take much more than 1 second, though, which is probably faster than you can paste manually

As compression takes place only after you trigger a paste, you will always notice it, as long as it takes longer than a few milliseconds.

I uploaded a very basic demonstration.
It shows the bug with the empty image in Discord and it also shows how it takes ~1 second for the conversion + pasting.


While trying to trigger the bug, I noticed something that may just be coincidence, or not:

  • The bug of an empty file could not be triggered, if I used Gwenview, only with a game run via wine, e.g. osu!
  • This may be because of xwayland, so I tried it with the wayland driver and could not trigger the bug anymore
  • As Discord also runs in xwayland, I tried launching it with wayland flags; the game in xwayland again and that way I could also not trigger the bug anymore

This makes no sense to me at all, because an image is an image, but maybe you can make more out of it.
Basically, this only seems to happen when the source and target are both xwayland windows.

I will for now keep Discord launched with wayland flags and observe if it happens again and report back.

Also, it was more likely to trigger, if I pasted “too fast” after capturing the image.