Linux (GTK) と OSX で透明なウィンドウ (アルファ チャネル付き) を描画したいと考えています。それを行うAPIはありますか?グローバルな透明度を設定したくないことに注意してください。アルファ レベルはピクセルごとに設定する必要があります。
この例のように、Windows の UpdateLayeredWindow 関数と同じ種類の API を探しています: Per Pixel Alpha Blend。
Linux (GTK) と OSX で透明なウィンドウ (アルファ チャネル付き) を描画したいと考えています。それを行うAPIはありますか?グローバルな透明度を設定したくないことに注意してください。アルファ レベルはピクセルごとに設定する必要があります。
この例のように、Windows の UpdateLayeredWindow 関数と同じ種類の API を探しています: Per Pixel Alpha Blend。
Mac OS X の場合は、RoundTransparentWindowサンプル コードを参照してください。カスタムの完全に透明なウィンドウを使用し、その中に図形を描画することで機能します。この例では、ハード エッジ + 全体的なアルファを持つ形状のみを使用していますが、任意のアルファを使用できます。
この例ではカスタム ウィンドウを使用していますが、 を呼び出して、同じ手法を使用して通常のウィンドウに穴を開けることができます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
この手法の主な制限は、標準のドロップ シャドウがアルファ ブレンドされたエッジとうまく相互作用しないことです。
このコードは、今年初めの実験フォルダーで見つかりました。この記事のどこまでを自分で書いたのか、またインターネット上の他の場所の例に基づいているのかは覚えていません。
この例では、中央に完全に不透明な GTK+ ボタンがある、部分的に透明な青いウィンドウを表示します。たとえば、ウィンドウ内のどこかにアルファブレンドされた 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;
}