可以截取一个圆形选定区域的屏幕截图吗?

当我们在Ubuntu上截取选定区域的屏幕截图时(使用Shift+Prt Scr或Ctrl+Shift+Prt Scr),我们总是选择一个矩形区域。所以,我知道我可以在像Inkscape这样的软件上编辑图像,将矩形图像变成圆形,但我想知道是否有一种配置可以改变,使我能够在截图时直接选择不同类型的形状(主要是圆形)。
这是可能的吗?

1那肯定是不可能的,圆的大小将会是多少,它的位置将会在哪里。Print Screen 要么打印整个屏幕(矩形),要么打印当前活动窗口(矩形)。 - Broadsworde
其实不是这样的,当我们使用Shift+PrintScreen或Ctrl+Shift+PrintScreen时,我们可以截取屏幕上已经选择的矩形区域...我正在使用Ubuntu 16.04,我只想将默认的矩形形状更改为圆形。 - Rafael Muynarsk
通过dconf编辑器可用的设置项(org/gnome/gnome-screenshot)包括:自动保存目录、边框效果、默认文件类型、延迟、包括边框、包括ICC配置文件、包括指针、上次保存目录,以及窗口截图(已弃用)。形状不作为一个设置项存在。 - Broadsworde
1@Broadsworde ksnapshop可以,为什么不呢?它有“自由发挥”的能力来制作最奇特的形状;不过,制作一个圆形... Ramuyko,你擅长制作圆形吗? - Rinzwind
@Ramuyko 我还有另一个想法,就是使用常规的矩形截图,然后从中剪切出最大可能的圆形区域,这样你就可以像往常一样选择区域。你对这个方法感兴趣吗? - dessert
@dessert 当然可以,那样非常完美,因为我可以在屏幕上选择一个可见的方块。 - Rafael Muynarsk
@Ramuyko 不,你误解了我的意思 - 你可以像往常一样用矩形选择,比如使用gnome-screenshot,然后脚本会将其裁剪成圆形(甚至是椭圆形,如果需要的话)。 - dessert
@dessert 是的...这正是我想的。使用gnome-screenshot,我可以直观地看到屏幕上正在进行的操作,这很酷。因此,在截取屏幕截图后,一个脚本会监视新的图像被拍摄,并根据原始图像的尺寸重新格式化图像,而不是需要按两次回车键创建的半径。你也是这么想的吗?我认为这也很有用 :) - Rafael Muynarsk
3个回答

我为圆形截图编写了一个小脚本,你需要以下软件包(尽管它也适用于其他截图程序和终端仿真器):
sudo apt install xdotool gnome-screenshot imagemagick xterm

剧本

#!/bin/bash

output=~/$(date +%F_%H%M%S).png
temp_screenshot=$(mktemp).png

read -p "Move cursor to center and press Enter"
eval $(xdotool getmouselocation --shell)
x_center=$X
y_center=$Y
read -p "Move cursor to edge and press Enter"
eval $(xdotool getmouselocation --shell)

gnome-screenshot -f $temp_screenshot

radius=$(bc <<<"sqrt(($X-$x_center)^2+($Y-$y_center)^2)")

convert $temp_screenshot -alpha on \( +clone -channel a -evaluate multiply 0 -draw "ellipse $x_center,$y_center $radius,$radius 0,360" \) -compose DstIn -composite -trim "$output"

将其保存为例如~/circular_screenshot.bash,并使用chmod +x ~/circular_screenshot.bash使其可执行。当您运行它时,脚本首先要求您将鼠标光标移动到中心位置并按下Enter,然后将其移动到边缘位置(无论哪个位置,脚本会根据距离计算半径)并再次按下Enter。屏幕在拍摄截图时会闪烁(我建议使用scrot $temp_screenshot代替,它不会显示这种奇怪的行为),并且使用ImageMagick的convert1来裁剪图像。输出以时间戳作为文件名保存在您的主目录中,您可以通过编辑脚本的output变量来更改此行为。

示例输出

example output

无需(或更好地说:使用不可见的)终端窗口进行呼叫

我猜你不想每次截屏时都有一个终端窗口挡住你的屏幕,所以这里有一个解决方案;按照以下方式调用脚本(假设脚本保存为~/circular_screenshot.bash):

xterm -geometry 0x0-1-1 -e ~/circular_screenshot.bash

这将在一个不可见的终端窗口中运行脚本(带有红色“X”和蓝色“T”的图标),您只需要确保在键入Enter时它处于焦点状态。 您可以使用桌面环境的设置将此命令分配给一个键盘快捷键。
由于ImageMagick非常强大,您可以根据需要调整此脚本以输出其他形状。我在上面使用了相同半径的椭圆来绘制圆形 - 将其更改为例如$radius,$(bc <<<"$radius*0.5")以获得偏心率大于0的椭圆。
1:我采用了imagemagick.org上的这个主题的方法。

现在如果xdotool能结合ksnapshot的自由选择功能,那就太好了! - Sebastian Stark
你可以在“所有设置”>“键盘”中添加自定义快捷方式,点击“+ 添加自定义快捷方式”,将此脚本放入命令字段,并将其分配给打印键。 - Mike
@SebastianStark 你有什么想法?一个不同的选择(也许类似于我的另一个想法)? - dessert
当我读到xdotool时,我想到一个使用xdotool的脚本,可以让鼠标光标在圆圈中移动,以利用ksnapshot的手绘选择功能。 - Sebastian Stark
@SebastianStark 哦,现在这是第三种方式 - 请编写一个脚本并添加一个答案!;) - dessert

我在这里发现了一些关于截图的事情。当我们在Ubuntu上进行截图时(我的是16.04版本),实际上我们使用的是一个叫做gnome-screenshot的软件。它是一个用C语言编写的开源软件,我们可以在GitHub上找到它的源代码,链接如下:this link

enter image description here

嗯,那里有一个名为 screenshot-area-selection.c 的文件回答了我的问题。这是一个有361行代码的文件,所以我不会在这里粘贴它。但就我对这个文件的理解(不多),它使用了许多围绕构建矩形形状的函数... 就像这段代码中一样:
create_select_window (void)
{
  GtkWidget *window;
  GdkScreen *screen;
  GdkVisual *visual;

  screen = gdk_screen_get_default ();
  visual = gdk_screen_get_rgba_visual (screen);

  window = gtk_window_new (GTK_WINDOW_POPUP);
  if (gdk_screen_is_composited (screen) && visual)
    {
      gtk_widget_set_visual (window, visual);
      gtk_widget_set_app_paintable (window, TRUE);
    }

  g_signal_connect (window, "draw", G_CALLBACK (select_window_draw), NULL);

  gtk_window_move (GTK_WINDOW (window), -100, -100);
  gtk_window_resize (GTK_WINDOW (window), 10, 10);
  gtk_widget_show (window);

  return window;
}

typedef struct {
  GdkRectangle rectangle;
  SelectAreaCallback callback;
  gpointer callback_data;
  gboolean aborted;
} CallbackData;

所以,我的结论是无法通过更改任何配置来使用gnome-screenshot进行截屏,因为它的代码结构不适用于这种操作...虽然可以下载代码,自行更改代码,重新编译并使用我个人定制的gnome-screenshot版本。

使用与已接受答案相同的想法,我创建了另一个脚本来进行六边形截屏,并在这里分享,以便对他人有用。

示例输出

example of hexagonal screenshot

剧本

#!/bin/bash

output=~/$(date +%F_%H%M%S).png
temp_screenshot=$(mktemp).png

read -p "Move cursor to center and press Enter"
eval $(xdotool getmouselocation --shell)
x1=$X
y1=$Y
read -p "Move cursor to edge and press Enter"
eval $(xdotool getmouselocation --shell)
x2=$X
y2=$Y

gnome-screenshot -f $temp_screenshot

radius=$(bc -l <<<"sqrt(($x2-$x1)^2+($y2-$y1)^2)")
ca=$(bc -l <<<"$radius/sqrt(3)") 
h=$(bc -l <<<"$radius/(sqrt(3)/2)")

P1_x=$(bc <<<"$x1+$ca")
P1_y=$(bc <<<"$y1+$radius")

P2_x=$(bc <<<"$x1+$h")
P2_y=$(bc <<<"$y1")

P3_x=$(bc <<<"$x1+$ca")
P3_y=$(bc <<<"$y1-$radius")

P4_x=$(bc <<<"$x1-$ca")
P4_y=$(bc <<<"$y1-$radius")

P5_x=$(bc <<<"$x1-$h")
P5_y=$(bc <<<"$y1")

P6_x=$(bc <<<"$x1-$ca")
P6_y=$(bc <<<"$y1+$radius")

convert $temp_screenshot -alpha on \
        \( +clone -channel a -evaluate multiply 0 -draw \
        "polygon $P1_x,$P1_y $P2_x,$P2_y $P3_x,$P3_y $P4_x,$P4_y $P5_x,$P5_y $P6_x,$P6_y" \) \
        -compose DstIn -composite -trim "$output"

这个过程与accepted answer完全相同。在这种情况下,我只更改了脚本名称:
"将其保存为例如~/hexagonal_screenshot.bash并使用chmod +x ~/hexagonal_screenshot.bash使其可执行。当您运行它时,脚本首先要求您将鼠标光标移动到中心位置并按Enter键,然后再将其移动到边缘位置(无论哪个,脚本会根据距离计算半径)并再次按Enter键。屏幕在截取屏幕截图时闪烁(我建议使用scrot $temp_screenshot而不是,因为它不显示这种奇怪的行为)。然后使用ImageMagick的convert来裁剪图像。输出以时间戳作为文件名保存在您的主目录中,您可以通过编辑脚本的output变量来更改此行为。"

附加信息

如果有人对所涉及的数学感兴趣,我来解释一下。要使用Imagemagick创建一个具有不同边数或不同形状的多边形,步骤是相同的:进行数学计算,并在代码的这部分添加或删除点:"polygon $P1_x,$P1_y $P2_x,$P2_y $P3_x,$P3_y $P4_x,$P4_y $P5_x,$P5_y $P6_x,$P6_y"

enter image description here