How do I render an image at 2x scale on a display at 2x scale?

I’m trying to render a GtkPicture like this:

file = Gio.File.new_for_path(self.image_path)
texture = Gdk.Texture.new_from_file(file)
picture = Gtk.Picture.new_for_paintable(texture)
picture.set_can_shrink(False) 
overlay.set_child(picture)

It works when the display is at 1x scale. But with a 2x scale display, the image is rendered blurry and two times as large as expected. How should I fix this?

I’m using GTK 4 on Wayland.

If the image happens to be an SVG, there was a similar sounding issue recently: svg not scaled with display scale since switch to librsvg (#7823) · Issues · GNOME / gtk · GitLab

No, the image is a PNG / webp / JPEG.

I find that there is a gtk_scaler_* API, but it is not exposed via GI. There is also a gdk_paintable_new_from_file_scaled API, but it is also not exposed via GI. I have to write in C?

I don’t think I completely understand the problem but would it not be possible to size the gtkpicture?

import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk
gi.require_version('Gdk', '4.0')
from gi.repository import Gdk
from gi.repository import Gio

class Main:
  def __init__(self, app):
    self.mainwin = Gtk.ApplicationWindow.new(app)
    self.image_path = "data.jpg"
    file = Gio.File.new_for_path(self.image_path)
    texture = Gdk.Texture.new_from_file(file)
    picture = Gtk.Picture.new_for_paintable(texture)
    picture.set_can_shrink(True)
    picture.set_size_request(texture.get_width() / picture.get_scale_factor(), -1)

    self.mainwin.set_child(picture)
    self.mainwin.set_default_size(texture.get_width() / picture.get_scale_factor(), -1)
    self.mainwin.set_visible(True)

app = Gtk.Application()
app.connect('activate', Main)
app.run(None)

1 Like

Oh, I think I now understand what you’re asking. You want to render a picture at device pixels, i.e. not scaled 2x along with the rest of the UI. Or, taken the other way around, compared to the UI, you want to render the picture at 0.5x, then it will match the device pixels.

Is that it?

Thanks, set_size_request works! I didn’t think I needed to manually calculate the size and shrink it. In GTK 3 era, rendering a GdkPixbuf onto a canvas like this made the result blurry.

Yes, that’s it.