Gtk.Image 在 HiDPI 显示器上
Gtk.Image on HiDPI displays
我使用由 GdkPixbuf.Pixbuf
支持的 Gtk.Image
来显示照片。我缩放照片以适应可用的 space 以响应父小部件的 size-allocate
信号。问题是在 HiDPI 显示器上,每个尺寸都是逻辑像素而不是设备像素,因此会发生以下情况:
- 如果我将
GdkPixbuf.Pixbuf
缩放到我从 size-allocate
信号获得的尺寸,照片会占用所需的物理 space 但它只使用了一半的分辨率显示(假设 2:1 设备像素与逻辑像素的比率)。
- 如果我将
GdkPixbuf.Pixbuf
缩放到 get_scale_factor()
倍我从 size-allocate
信号获得的尺寸,那么照片将占据物理 space 的两倍(即, 它不适合 window).
如何让 GTK 知道我提供给图像的 Pixbuf
对应于设备像素而不是逻辑像素?
更新:这是我尝试过的方法(这些是我未进行任何缩放的简化示例,只是试图显示未缩放的图像):
尝试 1:
image = Gtk.Image()
image.set_from_file("subpixel.png")
尝试 2:
surface = cairo.ImageSurface.create_from_png("subpixel.png")
image = Gtk.Image()
image.set_from_surface(surface)
尝试 3:
pb = GdkPixbuf.Pixbuf.new_from_file("subpixel.png")
image = Gtk.Image.new_from_pixbuf(pb)
self.add(image)
尝试 4:
pb = GdkPixbuf.Pixbuf.new_from_file("subpixel.png")
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, pb.get_width(), pb.get_height())
context = cairo.Context(surface)
Gdk.cairo_set_source_pixbuf(context, pb, 0, 0)
context.paint()
image = Gtk.Image()
image.set_from_surface(surface)
这通常是通过从像素数据创建开罗表面然后使用 gtk_image_set_from_surface()
来完成的。我不会说 Python,但在 C 中我是这样说的:
GdkPixbuf *pb = gdk_pixbuf_new_from_file(file, NULL);
if(pb) {
cairo_surface_t *s = gdk_cairo_surface_create_from_pixbuf(pb, 0, gtk_widget_get_window(w));
if(s) {
gtk_image_set_from_surface(GTK_IMAGE(w), s);
cairo_surface_destroy(s);
}
g_object_unref(pb);
}
这在这里工作正常。与 gtk_image_set_from_file()
相反,它不会使用逻辑像素,而是使用设备像素,因此永远不会应用缩放。
我使用由 GdkPixbuf.Pixbuf
支持的 Gtk.Image
来显示照片。我缩放照片以适应可用的 space 以响应父小部件的 size-allocate
信号。问题是在 HiDPI 显示器上,每个尺寸都是逻辑像素而不是设备像素,因此会发生以下情况:
- 如果我将
GdkPixbuf.Pixbuf
缩放到我从size-allocate
信号获得的尺寸,照片会占用所需的物理 space 但它只使用了一半的分辨率显示(假设 2:1 设备像素与逻辑像素的比率)。 - 如果我将
GdkPixbuf.Pixbuf
缩放到get_scale_factor()
倍我从size-allocate
信号获得的尺寸,那么照片将占据物理 space 的两倍(即, 它不适合 window).
如何让 GTK 知道我提供给图像的 Pixbuf
对应于设备像素而不是逻辑像素?
更新:这是我尝试过的方法(这些是我未进行任何缩放的简化示例,只是试图显示未缩放的图像):
尝试 1:
image = Gtk.Image()
image.set_from_file("subpixel.png")
尝试 2:
surface = cairo.ImageSurface.create_from_png("subpixel.png")
image = Gtk.Image()
image.set_from_surface(surface)
尝试 3:
pb = GdkPixbuf.Pixbuf.new_from_file("subpixel.png")
image = Gtk.Image.new_from_pixbuf(pb)
self.add(image)
尝试 4:
pb = GdkPixbuf.Pixbuf.new_from_file("subpixel.png")
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, pb.get_width(), pb.get_height())
context = cairo.Context(surface)
Gdk.cairo_set_source_pixbuf(context, pb, 0, 0)
context.paint()
image = Gtk.Image()
image.set_from_surface(surface)
这通常是通过从像素数据创建开罗表面然后使用 gtk_image_set_from_surface()
来完成的。我不会说 Python,但在 C 中我是这样说的:
GdkPixbuf *pb = gdk_pixbuf_new_from_file(file, NULL);
if(pb) {
cairo_surface_t *s = gdk_cairo_surface_create_from_pixbuf(pb, 0, gtk_widget_get_window(w));
if(s) {
gtk_image_set_from_surface(GTK_IMAGE(w), s);
cairo_surface_destroy(s);
}
g_object_unref(pb);
}
这在这里工作正常。与 gtk_image_set_from_file()
相反,它不会使用逻辑像素,而是使用设备像素,因此永远不会应用缩放。