gtkmm – example 22

This is part of a more general work dedicated to gtkmm accessible here. This example explains and shows how to resize an image with gtkmm. Let’s have a look at the Gdk::Pixbuf::scale function:

void Gdk::Pixbuf::scale	(
const Glib::RefPtr< Gdk::Pixbuf >& dest,
int 		dest_x,
int 		dest_y,
int 		dest_width,
int 		dest_height,
double 		offset_x,
double 		offset_y,
double 		scale_x,
double 		scale_y,
InterpType 	interp_type 
) const

scale



  • dest is the destination image buffer (Gdk::Pixbuf). The function scales and copies the image in a new one (dest). Memory is not automatically allocated for the destination buffer. It means that the image dest must be created previously to the call of Gdk::Pixbuf::scale. Width and height of dest must be in accordance with the other arguments of the function.
  • dest_x and dest_y are the coordinates of the top left point in the destination image. All the pixels on the left side of dest_x and on the upper side of dest_y will remain unchanged.
  • dest_width and dest_height are the size (width and height) of the area to update in the destination buffer.
  • offset_x and offset_y are the offset of the source image in the destination image’s frame.
  • scale_x and scale_y are the scale factor applied to the source image before the copy. A scale factor of 1 will keep the original image size. A scale factor of 2 will create an image twice the original and so one.
  • interp_type is the interpolation type used for the transformation. Four types can be used :

    • Gdk::INTERP_NEAREST (top left): nearest neighbor sampling; this is the fastest and lowest quality mode. Quality is normally unacceptable when scaling down, but may be OK when scaling up.
    • Gdk::INTERP_TILES (bottom right): this is an accurate simulation of the PostScript image operator without any interpolation enabled. Each pixel is rendered as a tiny parallelogram of solid color, the edges of which are implemented with antialiasing. It resembles nearest neighbor for enlargement, and bilinear for reduction.
    • Gdk::INTERP_BILINEAR (bottom left): Best quality/speed balance; use this mode by default. Bilinear interpolation. For enlargement, it is equivalent to point-sampling the ideal bilinear-interpolated image. For reduction, it is equivalent to laying down small tiles and integrating over the coverage area.
    • Gdk::INTERP_HYPER (top right): This is the slowest and highest quality reconstruction function. It is derived from the hyperbolic filters in Wolberg’s “Digital Image Warping”, and is formally defined as the hyperbolic-filter sampling the ideal hyperbolic-filter interpolated image (the filter is designed to be idempotent for 1:1 pixel mapping).

output2

Download

Source code


main.cpp

#include 
#include 


// Scale used for the demonstration
#define         SCALE           8.



int main(int argc, char* argv[])
{
    // Initialize gtkmm library
    Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");


    // Load the source image
    Glib::RefPtr image = Gdk::Pixbuf::create_from_file("gtk_icon.png");
    int width=image->get_width();
    int height=image->get_height();
    //image2=image; // = image->scale_simple(image->get_width()*scale,image->get_height()*scale,Gdk::INTERP_NEAREST);


    // __________________________
    // ::: Create output1.png :::

    // Create, fill and save the destination image
    Glib::RefPtr image2 = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB,true,8,width*SCALE,height*SCALE);
    image2->fill(0x0000FFA0);
    image2->save("output1.png","png");
    std::cout << "output1.png created" << std::endl;


    // __________________________
    // ::: Create output2.png :::

    // Scale and copy the first image in the destination image with several type of scalin method
    // Top left
    image->scale(image2,
                 10,10,
                 (width*SCALE)/2.-10,(height*SCALE)/2-10,
                 0,0,
                 SCALE,SCALE,
                 Gdk::INTERP_NEAREST);
    // Top right
    image->scale(image2,
                 (width*SCALE)/2.+10,10,
                 (width*SCALE)/2.-20,(height*SCALE)/2.-10,
                 0,0,
                 SCALE,SCALE,
                 Gdk::INTERP_HYPER);
    // Bottom left
    image->scale(image2,
                 10,(height*SCALE)/2.+10,
                 (width*SCALE)/2.-10,(height*SCALE)/2.-20,
                 0,0,
                 SCALE,SCALE,
                 Gdk::INTERP_BILINEAR);
    // Bottom right
    image->scale(image2,
                 (width*SCALE)/2.+10,(height*SCALE)/2.+10,
                 (width*SCALE)/2.-20,(height*SCALE)/2.-20,
                 0,0,
                 SCALE,SCALE,
                 Gdk::INTERP_TILES);
    // Save the output image
    image2->save("output2.png","png");
    std::cout << "output2.png created" << std::endl;


    // __________________________
    // ::: Create output3.png :::

    // Scale and translate the source image
    image2->fill(0x70707070);
    image->scale(image2,
                 20,20,
                 width*SCALE-40,height*SCALE-40,
                 -width*SCALE/2.,-height*SCALE/2.,
                 SCALE*2,SCALE*2,
                 Gdk::INTERP_BILINEAR);
    image2->save("output3.png","png");
    std::cout << "output3.png created" << std::endl;

    // __________________________
    // ::: Create output4.png :::

    // Scale and translate the source image
    image2->fill(0x70707070);
    image->scale(image2,
				 image2->get_width()/2.,image2->get_height()/2.,
				 image2->get_width()/2.,image2->get_height()/2.,
				 -width*SCALE,-height*SCALE,
                 SCALE*2,SCALE*2,
                 Gdk::INTERP_TILES);
    image2->save("output4.png","png");
    std::cout << "output4.png created" << std::endl;
    return 0;
}

outputs


output1
output2
output3
output4

Leave a Reply

Your email address will not be published. Required fields are marked *