gtkmm – exemple 22

Cet article fait parti d’un ensemble d’exemples et d’articles sur gtkmm consultables ici. Cet exemple explique et montre comme redimensionner une image avec gtkmm. Regardons en détail la fonction Gdk::Pixbuf::scale :

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 est le buffer image de destination (Gdk::Pixbuf). La fonction redimensionne et copie l’image source dans une nouvelle image (dest). La mémoire n’est pas automatiquement alouée. Cela signifie que l’image de destination dest doit être créée préalablement à l’appel de la fonction scale. La largeur et la hauteur de dest doivent être en accord avec les autres paramètres de la fonction.
  • dest_x et dest_y sont les coordonnées du point en haut à gauche de l’image de destination. Tous les pixels à gauche de dest_x et au dessus de dest_y ne seront pas modifiés.
  • dest_width et dest_height sont les dimensions (largeur et hauteur) de la zone à mettre à jour dans le buffer de destination.
  • offset_x et offset_y sont les décalages de l’image source dans le repère de l’image de destination.
  • scale_x et scale_y sont les facteurs d’échelle appliqués à l’image source avant la copie. Un facteur de 1 conservera les proportions de l’image originale. Un facteur de 2 doublera les dimensions par rapport à l’image originale et ainsi de suite.
  • interp_type est la méthode d’interpolation utilisée pour la transformation. Quatre méthodes peuvent être utilisées :

    • Gdk::INTERP_NEAREST (en haut à gauche): échantillonage par le plus proche voisin: c’est la méthode la plus rapide, mais elle produit la plus mauvaise qualité. La qualité est mauvaise pour les zooms arrières, en revanche, elle peut être acceptable pour les zooms avant.
    • Gdk::INTERP_TILES (en bas à droite): c’est une implémentation fidèle à l’opérateur image de PostScript sans interpolation. Chaque pixel est redessiné comme un petit parallélogramme d’une seule couleur, les contours sont dessinés avec un anticrénelage. Cela ressemble au plus proche voisin pour les agrandissements et la méthode bilinéaire pour les réductions.
    • Gdk::INTERP_BILINEAR (en bas à gauche): le meilleur compromis entre la qualité et la rapidité; utilisez ce mode par défaut. Pour l’agrandissement, c’est équivalent à l’échantillonnage de interpolation bilinéaire. Pour les réductions, c’est équivalent à une intégration sur la zone à redimensionner.
    • Gdk::INTERP_HYPER (en haut à droite): c’est la méthode la plus lente, mais aussi cette qui présente le meilleur résultat. C’est dérivé des filtres hyperboliques présentés dans l’ouvrage de Wolberg’s “Digital Image Warping”. Cette méthode est formellement définie comme la méthode idéale d’interpolation d’image.

output2

Téléchargement


Code source


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;
}

Résultats


output1
output2
output3
output4

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *