1

我想在 Linux (GTK) 和 OSX 上绘制透明窗口(带 alpha 通道)。有没有 API 可以做到这一点?请注意,我不想设置全局透明度,应该按像素设置 alpha 级别。

我正在寻找与 Windows 上的 UpdateLayeredWindow 函数相同类型的 API,如下例所示:Per Pixel Alpha Blend

4

2 回答 2

2

对于 Mac OS X,请参阅RoundTransparentWindow示例代码。它通过使用自定义的完全透明窗口并在其中绘制形状来工作。尽管该示例仅使用具有硬边 + 整体 alpha 的形状,但可以使用任意 alpha。

尽管该示例使用自定义窗口,但您可以使用相同的技术在普通窗口中打孔,方法是调用setOpaque:NO. 哈克示例:

@implementation ClearView

- (void)drawRect:(NSRect)rect
{
    if (mask == nil)  mask = [[NSImage imageNamed:@"mask"] retain];
    [self.window setOpaque:NO];
    [mask drawInRect:self.bounds
            fromRect:(NSRect){{0, 0},mask.size}
           operation:NSCompositeCopy
            fraction:1.0];
}

@end

这种技术的主要限制是标准投影不能很好地与 alpha 混合边缘交互。

于 2009-07-23T11:27:57.717 回答
1

我在今年早些时候的实验文件夹中找到了这段代码。我不记得我写了多少,有多少是基于 Internet 上其他地方的示例。

这个例子将显示一个部分透明的蓝色窗口,中间有一个完全不透明的 GTK+ 按钮。例如,在窗口内某处绘制一个 alpha 混合的 PNG 应该会导致它被正确合成。希望这将使您走上正确的道路。

用以下代码编译它:

$ gcc `pkg-config --cflags --libs gtk+-2.0` -o per-pixel-opacity per-pixel-opacity.c

现在看代码:

#include <gtk/gtk.h>

static gboolean on_window_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
    cairo_t *cr;
    cr = gdk_cairo_create(widget->window); // create cairo context

    cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 0.2);
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); // set drawing compositing operator
                                                   // SOURCE -> replace destination
    cairo_paint(cr); // paint source

    cairo_destroy(cr);

    return FALSE;
}

gint main(gint argc, gchar **argv)
{
    GtkWidget *window, *button, *vbox;
    GdkScreen *screen;
    GdkColormap *colormap;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    g_signal_connect(G_OBJECT(window), "delete-event", gtk_main_quit, NULL);
    g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(on_window_expose_event), NULL);

    gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
    gtk_container_set_border_width(GTK_CONTAINER(window), 20);

    gtk_widget_set_app_paintable(window, TRUE);

    screen = gtk_widget_get_screen(window);
    colormap = gdk_screen_get_rgba_colormap(screen);
    gtk_widget_set_colormap(window, colormap);

    button = gtk_button_new();
    gtk_button_set_label(GTK_BUTTON(button), "Don't Press!");

    gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(button));

    gtk_widget_show_all(window);

    gtk_main();

    return 0;
}
于 2009-08-03T04:02:42.297 回答