PHP-GTK2 Newsletter

PHP-GTK2 Tips & Techniques
FREE Newsletter
by kksou



Sample Code 102: How to scale an image?
Written by kksou   
Tuesday, 28 November 2006
Problem

You have set up a simple drag-and-drop image viewer in How to create a simple drag and drop image viewer?

Now you would like to scale the image as shown below:

Note: This example also shows how to popup multiple images using dialogs.

How to scale an image?


Solution

Sample Code
1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
<?php
$window = new GtkWindow();
$window->set_size_request(400, 300);
$window->connect_simple('destroy', array('Gtk','main_quit'));

$img = new GtkImage();
$img->drag_dest_set(Gtk::DEST_DEFAULT_ALL,
    array( array( 'text/uri-list', 0, 0)), Gdk::ACTION_COPY);
$img->connect('drag-data-received', 'on_drop', $img);

// Set up gtkentry to get scale_factor
$vbox = new GtkVBox();
$button = new GtkButton('scale');
$button->set_size_request(-1,24);
$hbox = new GtkHBox();
$hbox->pack_start(new GtkLabel('Scale (please enter percent value): '), 0, 0);
$scale_factor = new GtkEntry('');
$scale_factor->set_size_request(40, -1);
$button->connect('clicked', 'on_button', $scale_factor);
$hbox->pack_start($scale_factor, 0, 0);
$hbox->pack_start(new GtkLabel('%  '), 0, 0);
$hbox->pack_start($button, 0, 0);
$vbox->pack_start($hbox, 0, 0);
$vbox->pack_start($img);

$window->add($vbox);
$window->show_all();
Gtk::main();

// process drop
function on_drop($widget, $context, $x, $y, $data, $info, $time, $img) {
    $uri_list = explode("\n",$data->data);
    $img_file = $uri_list[0];
    $img_file = str_replace("file:///", "", $img_file);
    $img_file = str_replace("\r", "", $img_file);

    global $pixbuf;
    $pixbuf=GdkPixbuf::new_from_file($img_file); // note 1
    $width = $pixbuf->get_width();
    $height = $pixbuf->get_height();
    $img->set_from_pixbuf($pixbuf);
    global $window;
    $window->set_size_request($width, $height+24); // note 2
}

function on_button($button, $scale_factor_widget) {
    $scale_factor = $scale_factor_widget->get_text(); // get scale factor

  • Note that this is only 70% of the sample code. You have to be a registered member to see the entire sample code. Please login or register.
  • Registration is free and immediate.
  • Have some doubt about the registration? Please read this forum article.
Explanation
  1. Load the image into a pixbuf.
  2. Get the image width and height from the pixbuf, and adjust the window size accordingly. Note that we added 24 to the height, which is the height of the button.
  3. Calculate the new width and height based on the scale factor.
  4. Scale the image with GdkPixbuf::scale_simple(int dest_width, int dest_height, GdkInterpType interp_type). For GdkInterpType, you have the following options:
    • Gdk::INTERP_NEAREST: 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: 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: 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: 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).
  5. Display the image using the pixbuf.
  6. Show the image, but don't include $dialog->run so that we can popup multiple images.

Note

You can use this technique to generate your own thumbnails of your image libraries.

Also, as noted in How to get image size?, the window will only auto-expand, but will not auto-shrink. php-gtk1 used to have a method GtkWindow::set_policy() that supports auto-shrink. But this is no longer available in php-gtk2. Until they add this back, there is no easy one-liner that allows you to auto-shrink based on image size.


Related Links
 

Add comment


Security code
Refresh

< Prev   Next >

Blog - Forum - Privacy Policy - Contact Us
Copyright © 2006-2012. kksou.com. All Rights Reserved