ubuntuusers.de

Bash: Screenshot-Pipe mit convert und avifenc

Status: Ungelöst | Ubuntu-Version: Xubuntu 24.04 (Noble Numbat)
Antworten |

glaskugel

Anmeldungsdatum:
8. Juli 2010

Beiträge: 4224

Ich möchte die Screenshots von UHD-Monitoren verkleinern.

Zur Zeit verwende ich in etwa sowas für das aktive Fenster bei XFCE:

sh -c 'xfce4-screenshooter -w -s "Bilder/Screenshot_$(date +%Y-%m-%d_%H-%M-%S).avif"'

oder bei KDE

$ spectacle -baen -o "$HOME/Bilder/bildschirmfotos/screenshot_$(date +'%Y-%m-%d_%Hh%Mm%Ss').jpg"

Diese Befehle lege ich auf einen Shortcut.

Die Idee wäre nun, das Bild nach stdout zu schreiben und in eine Pipe mit convert zu geben.

Bei convert könnte ich dann zB so was machen

-resize 1000x

Ob die quality-Option bei Imagemagick und avif schon repariert ist, bin ich mir nicht sicher, aber könnte sein. Bei

-quality 10

stehen sich 50kB im Vergleich zum Original-avif mit 1,5MB von xfce4-screenshooter gegenüber. Die Qualität ist dann noch akzeptabel.

Eventuell konvertiert man das nicht mit convert sondern mit was anderem, zB avifenc in einer weiteren Pipe.

Es geht jetzt darum einen Screenshot nach Stdout zu machen bzw. irgendeine andere Lösung zu finden

Tools zum avif konvertieren:

https://linuxconfig.org/converting-images-to-avif-on-linux-including-jpg-png-and-webp-formats

https://www.luisllamas.es/en/how-to-convert-images-to-avif/

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6572

Wohnort: Hamburg

Die Idee wäre nun, das Bild nach stdout zu schreiben und in eine Pipe mit convert zu geben.

Du kannst das auch direkt mit Imagemagick machen:

import -window root screenshot.jpg

"root" ist der gesamte Bildschirm.

How to Capture Screens using magick import

2.2 Screenshot taking

glaskugel

(Themenstarter)

Anmeldungsdatum:
8. Juli 2010

Beiträge: 4224

$ import -window root -resize 1000x -quality 20 screenshot.avif

Ergebnis 5,5kB

Das ist schon mal ein Schritt weiter.

BTW, das funktioniert nicht:

$ import -window root -resize 1000x -quality 20 screenshot.heif

Der Befehl ist zwar fehlerfrei, aber das Ergebnis ist 3,3MB

Ich habe extra das Beispiel mit dem aktiven Fenster gebracht, weil ich da mit Schwierigkeiten rechne.

https://commandmasters.com/commands/magick-import-common/ Capture a Specific Window Given Its ID into a JPEG Image

magick import -window window_id path/to/output.jpg

Wie soll der Shortcut erkennen, welches Fenster aktiv ist?

glaskugel

(Themenstarter)

Anmeldungsdatum:
8. Juli 2010

Beiträge: 4224

Der Befehl ist zwar fehlerfrei, aber das Ergebnis ist 3,3MB

Da hat der eingangs von mir erwähnte Bug zugeschlagen.

$ import -window root -resize 1000x -quality 90 screenshot.heif

Die Datei hat die gleiche Größe wie bei "-quality 20".

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6572

Wohnort: Hamburg

Möglicherweise kann da xprop helfen.

glaskugel

(Themenstarter)

Anmeldungsdatum:
8. Juli 2010

Beiträge: 4224

Es sind Überlegungen in alle Richtungen denkbar. Man könnte notfalls den Screenshot in /tmp zwischenspeichern und statt einem Einzeiler ruft der Shortscut ein Script aufrufen, das dauert dann wohl am längsten.

https://wiki.archlinux.org/title/Screen_capture zeigt eine Menge an Scrrenshot-Programmen. Vielleicht entdeckt da ja wer was, das für stdout geeignet ist und idealerweise mit X11 und/oder wayland funktioniert.

https://gitlab.freedesktop.org/emersion/grim nennt für grim ein Fenster-Beispiel:

Grab a screenshot from the focused window under Sway, using swaymsg and jq:

grim -T "$(swaymsg -t get_tree | jq -j '.. | select(.type?) | select(.focused).foreign_toplevel_identifier')"

Das ist dann vermutlich auf KDE mit Wayland beschränlt.

Für X11 könnte man bei https://github.com/naelstrof/maim fündig werden. Ich blicke bei den Beispielen noch nicht durch, habe es gerade entdeckt.

Für XFCE ist das vorübergehend eine Lösung:

import -window root -resize 1600x -quality 20 "$HOME/Bilder/screenshot_$(date +'%Y-%m-%d_%H-%M-%S').avif"

TNTMaster

Anmeldungsdatum:
30. Juli 2009

Beiträge: 897

Möglicherweise kann da xprop helfen.

Seh ich auch so.

Das aktive Fenster kann man sich von xprop ausgeben lassen. Befehl schaut dann so aus:

import -window $(xprop -root _NET_ACTIVE_WINDOW | awk '{print $NF}') -resize 1000x -quality 20 screenshot.avif

Gruß TNT

glaskugel

(Themenstarter)

Anmeldungsdatum:
8. Juli 2010

Beiträge: 4224

Seh ich auch so.

Danke für das Beispiel, aber nur theoretisch:

$ time import -window $(xprop -root _NET_ACTIVE_WINDOW | awk '{print $NF}') -resize 1000x -quality 20 screenshot.avif

real	2m12.726s
user	0m0.556s
sys	0m0.112s

Ich denke, da ist Schreiben nach /tmp schneller. 2min für einen Screenshot ist nicht akzeptabel. Ein AMD Ryzen 9 7900 ist nun nicht so langsam, ich will da gar nicht an einen alten Intel Core i5-5300U in einem Notebook denken.

TNTMaster

Anmeldungsdatum:
30. Juli 2009

Beiträge: 897

glaskugel schrieb:

stehen sich 50kB im Vergleich zum Original-avif mit 1,5MB von xfce4-screenshooter gegenüber.

Nun, der xfce4-screenshooter erstellt auch png Bilder, keine avif

Welche Auflösung fährst du denn? Hier mit 2560x1440:

$ time import -window $(xprop -root _NET_ACTIVE_WINDOW | awk '{print $NF}') -resize 1000x -quality 20 /tmp/test.avif

real	0m0,235s
user	0m0,253s
sys	0m0,049s

glaskugel

(Themenstarter)

Anmeldungsdatum:
8. Juli 2010

Beiträge: 4224

Nun, der xfce4-screenshooter erstellt auch png Bilder, keine avif

Doch der erstellt auch avif. Ich habe gerade gelernt für Thunar braucht man libavif-gdk-pixbuf für die Bildvorschau.

Ich verwende in der Regel UHD-Monitore mit 3840x2160.

Verwendest du XFCE? Irgendwoher muss der Unterschied ja kommen, aber der zitierte Befehl wird fertig.

Ergänzung:

$ time sh -c 'xfce4-screenshooter -w -s "Bilder/Screenshot_$(date +%Y-%m-%d_%H-%M-%S).avif"'

real	0m0.333s
user	0m0.796s
sys	0m0.079s

Beim 2. Versuch schneller, aber noch immer langsam:

$ time import -window $(xprop -root _NET_ACTIVE_WINDOW | awk '{print $NF}') -resize 1000x -quality 20 screenshot.avif

real	0m5.662s
user	0m0.428s
sys	0m0.113s

Zum Vergleich:

$ time import -window root -resize 1600x -quality 20 "$HOME/Bilder/screenshot_$(date +'%Y-%m-%d_%H-%M-%S').avif"

real	0m0.319s
user	0m0.778s
sys	0m0.253s

Ich test mit:

$ inxi -G
Graphics:
  Device-1: Intel driver: xe v: kernel
  Device-2: AMD Raphael driver: amdgpu v: kernel
  Display: x11 server: X.Org v: 21.1.11 driver: X:
    loaded: amdgpu,modesetting unloaded: fbdev,vesa dri: iris gpu: xe
    resolution: 3840x2160~60Hz
  API: EGL v: 1.5 drivers: iris,kms_swrast,radeonsi,swrast
    platforms: gbm,x11,surfaceless,device
  API: OpenGL v: 4.6 compat-v: 4.5 vendor: intel mesa
    v: 25.0.7-0ubuntu0.24.04.2 renderer: Mesa Intel Graphics (BMG G21)
  API: Vulkan v: 1.3.275 drivers: N/A surfaces: xcb,xlib

glaskugel

(Themenstarter)

Anmeldungsdatum:
8. Juli 2010

Beiträge: 4224

Ich bin einen Schritt weiter.

$ time maim -i $(xdotool getactivewindow)  | convert - -resize 1600x -quality 20 "$HOME/Bilder/screenshot-maim-active_$(date +'%Y-%m-%d_%H-%M-%S').jpg"

real	0m0.312s
user	0m0.413s
sys	0m0.405s

Aber direkt mit avif klappt das nicht, dass ist ziemlich sicher der IM-Bug mit avif, den man im Web findet.

Also braucht es noch eine Pipe.

Jetzt braucht es was, das mit dem stdout von convert umgehen kann um avif zu erstellen.

Alternativ habe ich probiert, heif und jxl, sie sind von der Darstellung ok, aber 10-20x so groß. Das ist auch wieder der IM-Bug, der die quality-Option nicht berücksichtigt.

Probieren könnte man auch eine Pipe, die von stdin nach heif oder jxl konvertiert.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13323

Vielleich mal mit GraphicsMagick statt ImageMagick probieren. Mit - kann man Stdin oder Stdout adressieren.

glaskugel

(Themenstarter)

Anmeldungsdatum:
8. Juli 2010

Beiträge: 4224

$ maim  | convert - -resize 1600x png:- | avifenc --stdin  output.avif
Y4M header too small: (stdin)
ERROR: Cannot read y4m through standard input

alternativ:

$ maim  | convert - -resize 1600x PNG:- | avifenc --stdin  output.avif
Y4M header too small: (stdin)
ERROR: Cannot read y4m through standard input

Vielleicht ist avifenc zu alt:

$ avifenc -V
Version: 1.0.4 (dav1d [dec]:1.4.1, libgav1 [dec]:0.18.0, aom [enc/dec]:v3.8.2, rav1e [enc]:0.7.1 (UNKNOWN), svt [enc]:v1.7.0)
libyuv : available (1883)

Die Option "stdin" hatte ich ursprünglich bei meinen Suchen nichr gefunden.

$ dpkg -l | grep avif
ii  libavif-bin                                    1.0.4-1ubuntu3                             amd64        Library for handling .avif files (utilities)
ii  libavif-gdk-pixbuf:amd64                       1.0.4-1ubuntu3                             amd64        Library for handling .avif files (GDK pixbuf plugin)
ii  libavif16:amd64                                1.0.4-1ubuntu3                             amd64        Library for handling .avif files

Da gibt es noch Pakete, die nicht installiert sind:

~# aptitude search avif
i   libavif-bin                     - Bibliothek zur Verarbeitung von .avif-Date
p   libavif-dev                     - Library for handling .avif files (developm
i   libavif-gdk-pixbuf              - Library for handling .avif files (GDK pixb
i A libavif16                       - Bibliothek zur Verarbeitung von .avif-Date
p   libavifile-0.7-bin              - Werkzeugsatz für libavifile               
i   libavifile-0.7-common           - Werkzeugsatz für libavifile               
p   libavifile-0.7-dev              - Entwicklungs-Header-Dateien für libavifile
p   libavifile-0.7c2                - gemeinsam genutzte Bibliotheke zum Lesen/S
p   qt5-avif-image-plugin           - Qt plug-in to read/write AVIF images (Qt5 

glaskugel

(Themenstarter)

Anmeldungsdatum:
8. Juli 2010

Beiträge: 4224

$ maim  | convert - -resize 1600x PNG:- | cjxl - output.jxl
JPEG XL encoder v0.7.0 [AVX3_ZEN4,AVX3,AVX2,SSE4,SSSE3,SSE2]
Reading image data failed.

Bei https://github.com/libjxl/libjxl/issues/542 wird stdin diskutiert. Ich habe nicht kapiert was da letztlich für eine Syntax heraus gekommen ist.

glaskugel

(Themenstarter)

Anmeldungsdatum:
8. Juli 2010

Beiträge: 4224

maim  | avifenc --stdin  output.avif
Y4M header too small: (stdin)
ERROR: Cannot read y4m through standard input

Das Problem hat nichts mit Imagemagick zu tun.

$ maim  | cjxl - output.jxl
JPEG XL encoder v0.7.0 [AVX3_ZEN4,AVX3,AVX2,SSE4,SSSE3,SSE2]
Reading image data failed.

https://github.com/libjxl/libjxl/issues/542#issuecomment-916962295

It should work now for cjxl, and also input to djxl should work.

Antworten |