如何转储正在运行的 X 程序的图标?

如何转储正在运行的 X 程序的图标?

有没有办法获得正在运行的X程序的图标?当您在窗口之间切换时,您可以看到它的图标,例如通过xfwm4。

答案1

这对我有用。可能不适用于所有应用程序和所有窗口管理器。该pam格式至少受 ImageMagick 支持,因此您可以使用以下命令查看它display并将其转换为其他格式(如果需要)convert

xprop -notype 32c _NET_WM_ICON |
  perl -0777 -pe '@_=/\d+/g;
    printf "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n", splice@_,0,2;
    $_=pack "N*", @_;
    s/(.)(...)/$2$1/gs' > icon.pam

(然后单击您想要从中获取图标的窗口,另请参阅 xprop 的-id选项)

这个想法是使用 xprop 获取 32 位十进制整数列表形式的属性,并使用 perl 将其转换为图形格式(为简单起见,此处选择了 pam,尽管我必须重新排序字节,因为 _NET_WM_ICON 是 ARGB,而 pam 是 RGBA。

关于 pam 格式的说明。它是网络PBM格式,netpbm 是一个古老的 Unix 图像处理工具箱。然而,由于各种问题(主要是许可问题),较新的 netpbm 版本不是由 debian 提供的软件包,因此它的衍生产品(如 ubuntu)也是如此,这意味着大多数 pam 转换实用程序都不存在。在具有较新 netpbm 的其他系统上,您可以通过管道将上面的输出pamrgbatopng生成 png 图像)

答案2

基于@Stéphane Chazelas 惊人的片段我创建了一个脚本来转储不仅是第一个,而且全部给定窗口的图标到.png图像:

#!/bin/bash
if [[ "$1" == '--help' ]]; then
    echo "Show information or extract a window's icons to NAME-WIDTH.png"
    echo "Usage: ${0##*/} [NAME]"
    exit
fi

if [[ "$1" ]]; then
    cmd=(convert -set 'filename:w' '%w' - "${1}-%[filename:w].png")
else
    cmd=(identify -)
fi

split_icons() {
    xprop -notype 32c _NET_WM_ICON |
    awk -v RS=', | = ' '
        NR == 1         { h  = $1; i++; next }
        NR == i + 1     { x  = $1;        printf "%s = %s", h, x; next }
        NR == i + 2     { s  = x * $1 } { printf ", %s", $1 }
        NR == i + 2 + s { i += s + 2;     printf "\n" }
    '
}

to_pam() {
    perl -0777 -pe '@_=/\d+/g;
    printf "P7\nWIDTH %d\nHEIGHT %d\n", splice@_,0,2;
    printf "DEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n";
    $_=pack "N*", @_;
    s/(.)(...)/$2$1/gs'
}

while read -r data; do to_pam <<< "$data" | "${cmd[@]}"; done < <(split_icons)

如果没有任何用于显示图标信息的参数identify,则不会创建任何文件。根据给定的值NAME,它会提取图标并用于convert将它们另存为NAME-<width>.png.

用法示例:

$ extract-icons --help
Show information or extract a window's icons to NAME-WIDTH.png
Usage: extract-icons [NAME]

$ extract-icons  # ... click on firefox ...
-=>/tmp/magick-14339JS01_CgEl3Yi PAM 64x64 64x64+0+0 8-bit TrueColor sRGB 16.5KB 0.000u 0:00.000
-=>/tmp/magick-14342I14cdBFZKQIm PAM 16x16 16x16+0+0 8-bit TrueColor sRGB 1.09KB 0.000u 0:00.000
-=>/tmp/magick-14345gjMYsrl4Jhmh PAM 128x128 128x128+0+0 8-bit TrueColor sRGB 65.6KB 0.000u 0:00.000
-=>/tmp/magick-14348Wdmu9LGUEH0j PAM 32x32 32x32+0+0 8-bit TrueColor sRGB 4.16KB 0.000u 0:00.000
-=>/tmp/magick-14351HICEECbK3LRi PAM 48x48 48x48+0+0 8-bit TrueColor sRGB 9.28KB 0.000u 0:00.000

$ extract-icons firefox
$ ls -l
total 36.864
-rw-r--r-- 1 rodrigo rodrigo 14.882 2020-09-16 18:44 firefox-128.png
-rw-r--r-- 1 rodrigo rodrigo  1.175 2020-09-16 18:44 firefox-16.png
-rw-r--r-- 1 rodrigo rodrigo  2.265 2020-09-16 18:44 firefox-32.png
-rw-r--r-- 1 rodrigo rodrigo  3.870 2020-09-16 18:44 firefox-48.png
-rw-r--r-- 1 rodrigo rodrigo  5.996 2020-09-16 18:44 firefox-64.png

您可以获得完整的脚本,并添加一些选项,如下所示xdg-extract-icons在我的xdg-tools 存储库

答案3

我偶然发现博客文章。引用其中的话:

为了演示如何在实践中做到这一点,我编写了一个名为的小程序图形图标它允许用户选择正在运行的 X 应用程序的窗口并将提取的图标保存到作为参数提供的文件中。

答案4

使用linux libwnck就可以做到

#define WNCK_I_KNOW_THIS_IS_UNSTABLE = 1

#include <libwnck/libwnck.h>

int main(int argc,
         char **argv) {
    WnckScreen *screen;

    gdk_init(&argc, &argv);

    screen = wnck_screen_get_default();

    wnck_screen_force_update(screen);

    auto win = wnck_window_get(127926341); // 127926341 is window id, it can be get by linux cli xdotool or wmctrl or other many clis
    GdkPixbuf *r = wnck_window_get_icon(win);
    GError *err = NULL;
    gdk_pixbuf_save(r, "/tmp/prpr.png", "png", &err, "quality", "100", NULL);
    return 0;
}

我从这一页

相关内容