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
- 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.
- 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.
Téléchargement

gtkmm - example 22 16.09 KB
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



