Web lists-archives.com

Re: Resize all images that are part of a notebook




Thanks, Eric. 

I must have arrived at my "fix" the same time you came up with your much more elegant fix.
I did remove the sleep call. But my only other change was to change the line in the call back
from 
h = allocation->height;
to 
h = allocation->height * 0.75;

I realized I was resizing the image to the size of the entire window, which would trigger another resize, and another....etc.
Limiting to height to 3/4 of the window stops it from growing out of control. But the image degrades quickly.

But seeing your code with two call backs makes me think I need to try gtkmm, as I actually need 7 images in a notebook.
If I could make a class with the resize defined, I would not need 7 nearly identical callback routines.

On Thu, Aug 2, 2018 at 11:25 AM, <cecashon@xxxxxxx> wrote:

Hi Jack,

There are some problem spots in your code. There is a

g_signal_connect(window, "size-allocate", G_CALLBACK(resize_image), NULL);

in a loop and the resize_image function doesn't match the documentation.

https://developer.gnome.org/gtk3/stable/GtkWidget.html#GtkWidget-size-allocate

Careful with this because GTK doesn't always warn if you get your callbacks setup incorrectly. Then you might end up with some weird bugs that are hard to find in your code. You can change the names of the parameters in the callback but you need to keep the parameter types, number of parameters and return value the same as in the documentation.

There is a sleep(2) that you don't need in there.

g_strdup_printf() is safer and easier to use than sprintf with a buffer.

I am not sure how you want to have the images resized. If you want to have them resized with the main window that can be done. It is best if you get a pixbuf and keep it around so you can always resize the "original". This helps with reducing pixel loss. You could also use a drawing area, draw a frame in it and use that to drag and reduce or enlarge an image.

I gave it a try and may have a few mistakes myself. Maybe between the two you can figure out a good working solution.

Eric


/*
    gcc -Wall image1.c -o image1 `pkg-config gtk+-3.0 --cflags --libs`

    Tested on Ubuntu16.04 with GTK3.18.
*/

#include<gtk/gtk.h>

static void resize_image1(GtkWidget *scroll1, GdkRectangle *allocation, gpointer *data1)
  {
    g_print("Resize1\n");
    gdouble width=(gdouble)gdk_pixbuf_get_width((GdkPixbuf*)data1[1]);
    gdouble height=(gdouble)gdk_pixbuf_get_height((GdkPixbuf*)data1[1]);
    gdouble new_width=(gdouble)allocation->width;
    gdouble new_height=new_width/(width/height);

    if(new_height>(allocation->height))
      {
        new_height=(gdouble)allocation->height;
        new_width=new_height/(height/width);
      }

    GdkPixbuf *pxbscaled=gdk_pixbuf_scale_simple((GdkPixbuf*)data1[1], (gint)new_width, (gint)new_height, GDK_INTERP_BILINEAR);
    gtk_image_set_from_pixbuf(GTK_IMAGE(data1[0]), pxbscaled);
    g_object_unref(pxbscaled);
  }
static void resize_image2(GtkWidget *scroll, GdkRectangle *allocation, gpointer *data2)
  {
    g_print("Resize2\n");
    gdouble width=(gdouble)gdk_pixbuf_get_width((GdkPixbuf*)data2[1]);
    gdouble height=(gdouble)gdk_pixbuf_get_height((GdkPixbuf*)data2[1]);
    gdouble new_width=(gdouble)allocation->width;
    gdouble new_height=new_width/(width/height);

    if(new_height>(allocation->height))
      {
        new_height=(gdouble)allocation->height;
        new_width=new_height/(height/width);
      }

    GdkPixbuf *pxbscaled=gdk_pixbuf_scale_simple((GdkPixbuf*)data2[1], (gint)new_width, (gint)new_height, GDK_INTERP_BILINEAR);
    gtk_image_set_from_pixbuf(GTK_IMAGE(data2[0]), pxbscaled);
    g_object_unref(pxbscaled);
  }
int main(int argc, char *argv[])
  {
    gtk_init(&argc, &argv);

    GtkWidget *window=gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Notebook");
    gtk_window_set_default_size(GTK_WINDOW(window), 500, 500);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GdkPixbuf *pixbuf1=gdk_pixbuf_new_from_file_at_scale("image1.jpg", 500, 500, TRUE, NULL);
    GdkPixbuf *pixbuf2=gdk_pixbuf_new_from_file_at_scale("image2.jpg", 500, 500, TRUE, NULL);
   
    GtkWidget *image1=gtk_image_new_from_pixbuf(pixbuf1);
    gtk_widget_set_hexpand(image1, TRUE);
    gtk_widget_set_vexpand(image1, TRUE);

    GtkWidget *scroll1=gtk_scrolled_window_new(NULL, NULL);
    gtk_container_add(GTK_CONTAINER(scroll1), image1);
    gpointer data1[]={image1, pixbuf1};
    g_signal_connect(scroll1, "size-allocate", G_CALLBACK(resize_image1), data1);
  
    GtkWidget *grid1=gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid1), scroll1, 0, 0, 1, 1);   
   
    GtkWidget *image2=gtk_image_new_from_pixbuf(pixbuf2);
    gtk_widget_set_hexpand(image2, TRUE);
    gtk_widget_set_vexpand(image2, TRUE);

    GtkWidget *scroll2=gtk_scrolled_window_new(NULL, NULL);
    gtk_container_add(GTK_CONTAINER(scroll2), image2);
    gpointer data2[]={image2, pixbuf2};
    g_signal_connect(scroll2, "size-allocate", G_CALLBACK(resize_image2), data2);
   
    GtkWidget *grid2=gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid2), scroll2, 0, 0, 1, 1);

    GtkWidget *nb_label1=gtk_label_new("Page 1");
    GtkWidget *nb_label2=gtk_label_new("Page 2");
    GtkWidget *notebook=gtk_notebook_new();
    gtk_container_set_border_width(GTK_CONTAINER(notebook), 15);
    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), grid1, nb_label1);
    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), grid2, nb_label2);

    gtk_container_add(GTK_CONTAINER(window), notebook);

    gtk_widget_show_all(window);

    gtk_main();

    g_object_unref(pixbuf1);
    g_object_unref(pixbuf2);

    return 0;
  }



_______________________________________________
gtk-list mailing list
gtk-list@xxxxxxxxx
https://mail.gnome.org/mailman/listinfo/gtk-list