2

I want to display an SVG image in a GTK DrawingArea without losing quality when scaling. Currently, I am using the following code:

fn build_ui(application: &gtk::Application) {
    let window = gtk::ApplicationWindow::new(application);
    window.set_default_size(WIDTH, HEIGHT);
    let drawing_area = DrawingArea::new();
    window.add(&drawing_area);

    let file_data = include_str!("../file.svg").as_bytes();
    let loader = PixbufLoader::new();
    loader.write(file_data);
    loader.close();
    let pixbuf = loader.pixbuf().unwrap();
    let pixbuf = pixbuf.scale_simple(100, 100, InterpType::Hyper).unwrap();

    drawing_area.connect_draw(move |_, cr| {
        cr.set_source_pixbuf(&pixbuf, 0.0, 0.0);
        cr.paint();

        Inhibit(false)
    });

    window.show_all();
}

The original image size is 50x50 pixels, and I am scaling it to 100x100 pixels, which results in pixelation. This is because Pixbuf works with raster images. How can I work with vector output without losing quality at any scaling?

1 Answers1

0

To load an SVG image and scale it to whatever size you desire, you can use the from_file_at_scale() function. It takes four arguments: the path to the image file, the width to scale it to, the height to scale it to, and a bool to control whether or not the aspect ratio is preserved.

So, instead of all the PixbufLoader shenanigans, you can load and scale your image in one line, like this:

let pixbuf = gdk_pixbuf::Pixbuf::from_file_at_scale(&Path::new("/path/to/file.svg"), 100, 100, true).unwrap();

Putting this into a full program, it will look something like this:

use gtk::prelude::*;
use gtk;
use gdk_pixbuf;
use std::path::Path;

fn create_window(application: &gtk::Application) {
    let window = gtk::ApplicationWindow::new(application);
    let drawing_area = gtk::DrawingArea::new();
    window.add(&drawing_area);

    // Load and scale the image in one line
    let pixbuf = gdk_pixbuf::Pixbuf::from_file_at_scale(&Path::new("/path/to/file.svg"), 100, 100, true).unwrap();

    drawing_area.connect_draw(move |_, cr| {
        cr.set_source_pixbuf(&pixbuf, 0.0, 0.0);
        cr.paint();

        Inhibit(false)
    });

    window.show_all();
}

fn main() {
    // Create the application
    let app = gtk::Application::builder()
        .application_id("scale.image.demo")
        .build();
    app.connect_activate(create_window);
    app.run();
}
Sylvester Kruin
  • 3,294
  • 5
  • 16
  • 39