Bug 465781 - Spectacle doesn't follow image format when copying image
Summary: Spectacle doesn't follow image format when copying image
Status: RESOLVED FIXED
Alias: None
Product: Spectacle
Classification: Applications
Component: General (show other bugs)
Version: 22.12.2
Platform: Arch Linux Linux
: NOR minor
Target Milestone: ---
Assignee: Boudhayan Gupta
URL:
Keywords:
: 468883 (view as bug list)
Depends on:
Blocks:
 
Reported: 2023-02-15 17:17 UTC by [object Object]
Modified: 2024-08-23 21:07 UTC (History)
4 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description [object Object] 2023-02-15 17:17:21 UTC
SUMMARY
When copying a screenshot from spectacle, the image format set in the settings isn't copied - a png seems to always be used, while dragging and dropping the image into an app uses the format I set (webp) instead

STEPS TO REPRODUCE
1. Take a screenshot with spectacle
2. Copy the screenshot and paste it into an app, compare with dragging the screenshot into an app

OBSERVED RESULT
A PNG is pasted when copying and pasting, while WEBP is used when dragging and dropping the image

EXPECTED RESULT
Both methods to use the WEBP format

SOFTWARE/OS VERSIONS
KDE Plasma Version: 5.27.0
KDE Frameworks Version: 5.103.0
Qt Version: 5.15.8
Comment 1 guimarcalsilva 2023-02-16 02:23:42 UTC
Can you tell what application you're pasting into? On Dolphin, it shows a dialog and you can choose the format you want. Gnome Files and Nemo did not allow me to paste directly from the clipboard to them. This information would help developers diagnose the issue.
Comment 2 [object Object] 2023-02-16 02:55:13 UTC
(In reply to guimarcalsilva from comment #1)
> Can you tell what application you're pasting into? On Dolphin, it shows a
> dialog and you can choose the format you want. Gnome Files and Nemo did not
> allow me to paste directly from the clipboard to them. This information
> would help developers diagnose the issue.

I'm pasting the image into Firefox, but you're right as Dolphin asks me which format to choose
Comment 3 Nate Graham 2023-02-17 20:23:40 UTC
Cannot reproduce with GIMP using Spectacle from current git master; when I have the format set to JPEG, copying and pasting into GIMP gives me image data that's stripped of transparency and exhibits JPEG compression, as expected.

What website in Firefox are you pasting into?
Comment 4 [object Object] 2023-02-17 20:25:21 UTC
Discord, although I'll try some other websites/apps and post another comment
Comment 5 Bug Janitor Service 2023-03-04 03:45:51 UTC
Dear Bug Submitter,

This bug has been in NEEDSINFO status with no change for at least
15 days. Please provide the requested information as soon as
possible and set the bug status as REPORTED. Due to regular bug
tracker maintenance, if the bug is still in NEEDSINFO status with
no change in 30 days the bug will be closed as RESOLVED > WORKSFORME
due to lack of needed information.

For more information about our bug triaging procedures please read the
wiki located here:
https://community.kde.org/Guidelines_and_HOWTOs/Bug_triaging

If you have already provided the requested information, please
mark the bug as REPORTED so that the KDE team knows that the bug is
ready to be confirmed.

Thank you for helping us make KDE software even better for everyone!
Comment 6 [object Object] 2023-03-04 05:37:02 UTC
I've tried some other apps - QT (neochat, just uses the PNG) and GTK (nautilus, doesn't let me paste at all), so this might just be issue on the app's side
Comment 7 Noah Davis 2023-03-07 09:00:42 UTC
I can confirm this by doing the following:

1. Open Spectacle
2. Open the Save category in the settings dialog and pick the JPG format with 1% quality.
2. Check "Include window titlebar and borders"
3. Do an Active Window capture of an unmaximized window so that window shadows end up in the screenshot.
4. Click Copy.
5. Open an image editor with a checkered background for transparency.
6. Paste the copied image.

You should see that the shadows are semi-transparent and the image doesn't have any lossy compression.
Comment 8 Noah Davis 2023-03-07 09:06:52 UTC
This bug could be caused by a limitation of how QMimeData::setImageData() works. There is a difference between how Spectacle's drag & drop and copy image actions handle images.

Drag and Drop:

0. A screenshot is taken and potentially not saved. It is stored as a QPixmap. This can happen long before the drag starts as part of a separate series of actions and background processes.
1. Saves a temporary file with the expected format.
2. Adds the temporary file url to a QMimeData object via QMimeData::setUrls()
3. A QDrag object has the QMimeData added to it via QDrag::setMimeData()
4. The drag action begins.
5. The dropped content could be interpreted as a file path for the temporary file or as an image, depending on how an application handles the url.

Copy Image to Clipboard:

0. A screenshot is taken and potentially not saved. It is stored as a QPixmap. This can happen long before the drag starts as part of a separate series of actions and background processes.
1. The QPixmap is converted to a QImage and added to a QMimeData object via QMimeData::setImageData(). Internally, the mimetype for images copied in this manner is "application/x-qt-image", not PNG. This mimetype is just means that the content should be treated as a QImage object when consumed by other software made with Qt.
2. Data with the custom mimetype "x-kde-force-image-copy" is also added via QMimeData::setData(). This is a hint to Klipper that it should store the image in history even if the user has chosen not to store non-text content in Klipper's history. It only has an effect when an image has the "application/x-qt-image" mimetype.
3. The QMimeData object is sent to the system clipboard via KSystemClipboard::setMimeData().

Urls for images are shown in Klipper history not as URLs, but as images, even when the user has chosen not to save non-text content in history. The hint data that was added for copying to clipboard would not be necessary if we were to copy a temporary file url instead of a QImage. That would likely resolve this bug report, but I'm not sure if we can do that without causing other problems. The clipboard contents may need to live for far longer than the temporary file would (this obviously does not apply to files that were already saved normally). With drag & drop, it's expected that the dragged content will immediately be consumed only once when the drop is completed, making it unnecessary to keep the temporary file. I also don't know all the potential side effects of copying urls instead of raw image data. The likelihood could be low, but it's possible that some apps may not behave the way they're expected to behave when pasting image URLs instead of raw image data.

Oddly, you don't get a thumbnail of the copied application/x-qt-image content when storing non-text content in history is disabled, but the image content stored in klipper still works as expected.
Comment 9 Noah Davis 2023-03-07 09:10:02 UTC
Just so it's clear why we might want to fix this bug, what is the use case for wanting a specific format for unsaved images copied to the clipboard?
Comment 10 [object Object] 2023-03-07 15:27:17 UTC
(In reply to Noah Davis from comment #9)
> Just so it's clear why we might want to fix this bug, what is the use case
> for wanting a specific format for unsaved images copied to the clipboard?

The same as the use case is for changing the image format in spectacle - to make the screenshot smaller for pasting in discord, etc. which usually have an image size limit
Comment 11 Nate Graham 2023-03-07 18:13:30 UTC
I'd say the reason is to save space and bandwidth when copying into other apps. I use the feature in question to paste auto-copied-but-not-saved images from Spectacle into chat apps. If the images are JPEGs, they upload a lot faster then if they're PNGs. I have a 4k screen and use 200% scale, so PNG images can be quite huge.
Comment 12 Nate Graham 2023-03-07 18:13:36 UTC
Hah, same reason.
Comment 13 Noah Davis 2023-04-24 00:02:02 UTC
*** Bug 468883 has been marked as a duplicate of this bug. ***
Comment 14 Bug Janitor Service 2023-11-22 12:07:15 UTC
A possibly relevant merge request was started @ https://invent.kde.org/graphics/spectacle/-/merge_requests/292
Comment 15 Noah Davis 2023-11-22 21:24:50 UTC
Git commit e73b6d98542388db6c12c9f70145bb7abe56e5a0 by Noah Davis.
Committed on 22/11/2023 at 22:24.
Pushed by ndavis into branch 'master'.

Save image as temp file, then copy data when copying image

Now you can see a thumbnail of the image you copied in a notification
when only copying an image. The image is in whatever format you just
saved (if saving and copying image) or the default image format.

There is a known minor flaw where if you click the image thumbnail to open it in an image viewer, the image will be deleted before it can be viewed. This is because the image is in the temp dir, so it gets deleted when spectacle is closed.
Related: bug 422874

M  +21   -1    src/ExportManager.cpp

https://invent.kde.org/graphics/spectacle/-/commit/e73b6d98542388db6c12c9f70145bb7abe56e5a0
Comment 16 Bug Janitor Service 2024-08-13 01:11:08 UTC
A possibly relevant merge request was started @ https://invent.kde.org/graphics/spectacle/-/merge_requests/388
Comment 17 Bug Janitor Service 2024-08-16 13:13:27 UTC
A possibly relevant merge request was started @ https://invent.kde.org/graphics/spectacle/-/merge_requests/391
Comment 18 Noah Davis 2024-08-23 20:34:21 UTC
Git commit 83c9a81f3797140740ef9f31e2e6d4e1174115be by Noah Davis.
Committed on 23/08/2024 at 20:32.
Pushed by ndavis into branch 'master'.

Go back to copying images with setImageData

A previous change was made based on a wrong assumption that you could only
copy one format of image data and that the program doing the copying decides
the format that gets pasted.

The truth is that the app doing the copying gets to decide which formats
are sent to the clipboard and can send multiple types of data, but not which
format gets pasted. Only the app receiving the paste gets to decide which
format gets pasted. If it doesn't support the copied format, nothing will be
pasted. Because of this, images should be copied as uncompressed images. If
you want to paste a JPEG into Firefox/Chromium/Electron apps directly, you
can't really do that. You have to save a JPEG file and then copy the file as
a file URL. I'd like to do that instead so that the copied image can always
be compressed in the preferred format, but Flatpak apps currently can't use
/tmp without the user adding explicit permission specifically for /tmp.

Another issue with trying to copy images directly in the preferred format is
that lossy compressed formats like JPEG will be decompressed when Spectacle
closes, expanding 2-8x their compressed size. This is likely an issue with
Klipper (probably HistoryImageItem) and maybe KSystemClipboard.
Related: bug 485096, bug 465972

M  +26   -20   src/ExportManager.cpp

https://invent.kde.org/graphics/spectacle/-/commit/83c9a81f3797140740ef9f31e2e6d4e1174115be
Comment 19 Noah Davis 2024-08-23 21:07:47 UTC
Git commit 92a59d38ddf1c620a9c318d3f109f202c12c76d4 by Noah Davis.
Committed on 23/08/2024 at 21:07.
Pushed by ndavis into branch 'release/24.08'.

Go back to copying images with setImageData

A previous change was made based on a wrong assumption that you could only
copy one format of image data and that the program doing the copying decides
the format that gets pasted.

The truth is that the app doing the copying gets to decide which formats
are sent to the clipboard and can send multiple types of data, but not which
format gets pasted. Only the app receiving the paste gets to decide which
format gets pasted. If it doesn't support the copied format, nothing will be
pasted. Because of this, images should be copied as uncompressed images. If
you want to paste a JPEG into Firefox/Chromium/Electron apps directly, you
can't really do that. You have to save a JPEG file and then copy the file as
a file URL. I'd like to do that instead so that the copied image can always
be compressed in the preferred format, but Flatpak apps currently can't use
/tmp without the user adding explicit permission specifically for /tmp.

Another issue with trying to copy images directly in the preferred format is
that lossy compressed formats like JPEG will be decompressed when Spectacle
closes, expanding 2-8x their compressed size. This is likely an issue with
Klipper (probably HistoryImageItem) and maybe KSystemClipboard.
Related: bug 485096, bug 465972


(cherry picked from commit 83c9a81f3797140740ef9f31e2e6d4e1174115be)

Co-authored-by: Noah Davis <noahadvs@gmail.com>

M  +26   -20   src/ExportManager.cpp

https://invent.kde.org/graphics/spectacle/-/commit/92a59d38ddf1c620a9c318d3f109f202c12c76d4