cropper
diff cropper.c @ 18:9d6e8105b145
rename
author | meillo@marmaro.de |
---|---|
date | Thu, 04 Mar 2010 19:34:39 +0100 |
parents | main.c@4453456abad1 |
children | 762de8cee1e4 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/cropper.c Thu Mar 04 19:34:39 2010 +0100 1.3 @@ -0,0 +1,351 @@ 1.4 +#include <sys/types.h> 1.5 +#include <sys/stat.h> 1.6 +#include <unistd.h> 1.7 +#include <string.h> 1.8 +#include <stdio.h> 1.9 + 1.10 +#include <gtk/gtk.h> 1.11 +#include <gdk/gdkkeysyms.h> 1.12 +#include <gdk-pixbuf/gdk-pixbuf.h> 1.13 + 1.14 + 1.15 + 1.16 + 1.17 +GtkWidget* cropper_window; 1.18 +char* image_filename; 1.19 + 1.20 +/* from interface.h */ 1.21 +GtkWidget* create_cropper_window(void); 1.22 +GtkWidget* image_area; 1.23 +GdkPixbuf* image_buffer; 1.24 + 1.25 +int w, h, x, y; 1.26 + 1.27 +int image_width; 1.28 +int image_height; 1.29 +float inc = 0.3; 1.30 +float zoom = 1.0; 1.31 + 1.32 +/* from callbacks.h */ 1.33 +double ratio; 1.34 + 1.35 +void crop(void); 1.36 +gboolean on_key_press(GtkWidget* window, GdkEventKey* pKey, gpointer userdata); 1.37 +void on_cropper_window_create(GtkObject* object, gpointer user_data); 1.38 +void on_cropper_window_destroy(GtkObject* object, gpointer user_data); 1.39 + 1.40 + 1.41 + 1.42 + 1.43 + 1.44 +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ 1.45 + g_object_set_data_full(G_OBJECT(component), name, \ 1.46 + gtk_widget_ref(widget),(GDestroyNotify) gtk_widget_unref) 1.47 + 1.48 +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ 1.49 + g_object_set_data(G_OBJECT(component), name, widget) 1.50 + 1.51 + 1.52 +/* 1.53 + * This function returns a widget in a component created by Glade. 1.54 + * Call it with the toplevel widget in the component (i.e. a window/dialog), 1.55 + * or alternatively any widget in the component, and the name of the widget 1.56 + * you want returned. 1.57 + */ 1.58 +GtkWidget* 1.59 +lookup_widget(GtkWidget* widget, const gchar* widget_name) 1.60 +{ 1.61 + GtkWidget* parent; 1.62 + GtkWidget* found_widget; 1.63 + 1.64 + for (;;) { 1.65 + if (GTK_IS_MENU(widget)) { 1.66 + parent = gtk_menu_get_attach_widget(GTK_MENU(widget)); 1.67 + } else { 1.68 + parent = widget->parent; 1.69 + } 1.70 + if (!parent) { 1.71 + parent = (GtkWidget*) g_object_get_data(G_OBJECT(widget), "GladeParentKey"); 1.72 + } 1.73 + if (parent == NULL) { 1.74 + break; 1.75 + } 1.76 + widget = parent; 1.77 + } 1.78 + 1.79 + found_widget = (GtkWidget*) g_object_get_data(G_OBJECT(widget), widget_name); 1.80 + if (!found_widget) { 1.81 + g_warning("Widget not found: %s", widget_name); 1.82 + } 1.83 + return found_widget; 1.84 +} 1.85 + 1.86 + 1.87 + 1.88 +GtkWidget* 1.89 +create_cropper_window(void) 1.90 +{ 1.91 + GtkWidget *cropper_window; 1.92 + GtkWidget *dialog_vbox1; 1.93 + GtkWidget *status; 1.94 + GtkWidget *label1; 1.95 + GtkWidget *label2; 1.96 + 1.97 + 1.98 + cropper_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 1.99 + gtk_widget_set_name(cropper_window, "cropper_window"); 1.100 + gtk_container_set_border_width(GTK_CONTAINER(cropper_window), 6); 1.101 + gtk_window_set_title(GTK_WINDOW(cropper_window), "cropper-0.2"); 1.102 + 1.103 + dialog_vbox1 = gtk_vbox_new(FALSE, 6); 1.104 + gtk_widget_set_name(dialog_vbox1, "dialog_vbox1"); 1.105 + gtk_widget_show(dialog_vbox1); 1.106 + gtk_container_add(GTK_CONTAINER(cropper_window), dialog_vbox1); 1.107 + 1.108 + 1.109 + status = gtk_hbox_new(FALSE, 0); 1.110 + gtk_widget_set_name(status, "status"); 1.111 + gtk_widget_show(status); 1.112 + gtk_box_pack_end(GTK_BOX(dialog_vbox1), status, FALSE, FALSE, 0); 1.113 + 1.114 + label1 = gtk_label_new("zoom:"); 1.115 + gtk_widget_set_name(label1, "label1"); 1.116 + gtk_widget_show(label1); 1.117 + gtk_box_pack_start(GTK_BOX(status), label1, FALSE, FALSE, 0); 1.118 + 1.119 + label2 = gtk_label_new("1.0"); 1.120 + gtk_widget_set_name(label2, "label2"); 1.121 + gtk_widget_show(label2); 1.122 + gtk_box_pack_start(GTK_BOX(status), label2, FALSE, FALSE, 0); 1.123 + 1.124 +/* image_area */ 1.125 + image_buffer = gdk_pixbuf_new_from_file(image_filename, NULL); 1.126 + image_area = gtk_image_new_from_pixbuf(image_buffer); 1.127 + 1.128 + gtk_widget_set_name(image_area, "image_area"); 1.129 + gtk_widget_show(image_area); 1.130 + gtk_box_pack_start(GTK_BOX(dialog_vbox1), image_area, TRUE, TRUE, 0); 1.131 + 1.132 + 1.133 + 1.134 + 1.135 + 1.136 +g_signal_connect(G_OBJECT(cropper_window), "show", 1.137 + G_CALLBACK(on_cropper_window_create), NULL); 1.138 + 1.139 +g_signal_connect(G_OBJECT(cropper_window), "destroy", 1.140 + G_CALLBACK(on_cropper_window_destroy), NULL); 1.141 + 1.142 +g_signal_connect(cropper_window, "key-press-event", 1.143 + G_CALLBACK(on_key_press), NULL); 1.144 + 1.145 + 1.146 + /* Store pointers to all widgets, for use by lookup_widget(). */ 1.147 + 1.148 + GLADE_HOOKUP_OBJECT_NO_REF(cropper_window, cropper_window, "cropper_window"); 1.149 + GLADE_HOOKUP_OBJECT(cropper_window, dialog_vbox1, "dialog_vbox1"); 1.150 + 1.151 + GLADE_HOOKUP_OBJECT(cropper_window, label1, "label1"); 1.152 + GLADE_HOOKUP_OBJECT(cropper_window, label2, "label2"); 1.153 + GLADE_HOOKUP_OBJECT(cropper_window, status, "status"); 1.154 + GLADE_HOOKUP_OBJECT(cropper_window, image_area, "image_area"); 1.155 + GLADE_HOOKUP_OBJECT(cropper_window,(GtkWidget*) image_buffer, "image_buffer"); 1.156 + 1.157 + 1.158 + return cropper_window; 1.159 +} 1.160 + 1.161 + 1.162 + 1.163 + 1.164 + 1.165 + 1.166 + 1.167 + 1.168 + 1.169 + 1.170 + 1.171 + 1.172 + 1.173 + 1.174 + 1.175 + 1.176 + 1.177 + 1.178 + 1.179 + 1.180 + 1.181 +void 1.182 +update_title(char* zoom) 1.183 +{ 1.184 + char title[128]; 1.185 + snprintf(title, 128, "cropper (%s) %dx%d+%d+%d", zoom, w, h, x, y); 1.186 + gtk_window_set_title(GTK_WINDOW(cropper_window), title); 1.187 +} 1.188 + 1.189 + 1.190 +/* zoom */ 1.191 +void 1.192 +set_zoom() 1.193 +{ 1.194 + static GdkPixbuf* pixbuf_new; 1.195 + g_object_unref(pixbuf_new); 1.196 + 1.197 + pixbuf_new = gdk_pixbuf_scale_simple(image_buffer, image_width*zoom, image_height*zoom, 1.198 + GDK_INTERP_BILINEAR); 1.199 + gtk_image_set_from_pixbuf((GtkImage*) lookup_widget(cropper_window, "image_area"), pixbuf_new); 1.200 +} 1.201 + 1.202 +void 1.203 +on_zoom_in_button_clicked(GtkObject* object, gpointer user_data) 1.204 +{ 1.205 + zoom *= 1 + inc; 1.206 + set_zoom(); 1.207 +} 1.208 + 1.209 +void 1.210 +on_zoom_out_button_clicked(GtkObject* object, gpointer user_data) 1.211 +{ 1.212 + zoom *= 1 - inc; 1.213 + set_zoom(); 1.214 +} 1.215 + 1.216 +void 1.217 +on_zoom_100_button_clicked(GtkObject* object, gpointer user_data) 1.218 +{ 1.219 + zoom = 1.0; 1.220 + set_zoom(); 1.221 +} 1.222 + 1.223 +void 1.224 +on_zoom_fit_button_clicked(GtkObject* object, gpointer user_data) 1.225 +{ 1.226 + int w, h; 1.227 + float zw, zh; 1.228 + GtkWidget* image_a; 1.229 + 1.230 + image_a = (GtkWidget*) lookup_widget(cropper_window, "image_area"); 1.231 + gdk_drawable_get_size(image_a->window, &w, &h); 1.232 + 1.233 + zw = w*1.0 / image_width; 1.234 + zh = h*1.0 / image_height; 1.235 + 1.236 + zoom = (zw < zh) ? zw : zh; 1.237 + set_zoom(); 1.238 +} 1.239 + 1.240 + 1.241 + 1.242 + 1.243 + 1.244 + 1.245 + 1.246 +void 1.247 +crop(void) 1.248 +{ 1.249 + char crop_call[256]; 1.250 + 1.251 + sprintf(crop_call, "echo \"convert -crop %ix%i+%i+%i %s cropped_%s\"", 1.252 + gtk_spin_button_get_value_as_int((GtkSpinButton*) lookup_widget(cropper_window, 1.253 + "crop_width_spinbutton")), 1.254 + gtk_spin_button_get_value_as_int((GtkSpinButton*) lookup_widget(cropper_window, 1.255 + "crop_height_spinbutton")), 1.256 + gtk_spin_button_get_value_as_int((GtkSpinButton*) lookup_widget(cropper_window, 1.257 + "crop_x_spinbutton")), 1.258 + gtk_spin_button_get_value_as_int((GtkSpinButton*) lookup_widget(cropper_window, 1.259 + "crop_y_spinbutton")), 1.260 + image_filename, 1.261 + image_filename 1.262 + ); 1.263 + system(crop_call); 1.264 + gtk_main_quit(); 1.265 +} 1.266 + 1.267 + 1.268 +void 1.269 +on_cropper_window_create(GtkObject* object, gpointer user_data) 1.270 +{ 1.271 + image_width = gdk_pixbuf_get_width(image_buffer); 1.272 + image_height = gdk_pixbuf_get_height(image_buffer); 1.273 + 1.274 + /* 1.275 + image_buffer = gdk_pixbuf_new_from_file(image_filename, NULL); 1.276 + image_area = gtk_image_new_from_pixbuf(image_buffer); 1.277 + 1.278 + int w, h; 1.279 + GtkWidget* image_a; 1.280 + 1.281 + image_a = (GtkWidget*) lookup_widget(cropper_window, "image_area"); 1.282 + gdk_drawable_get_size(image_a->window, &w, &h); 1.283 + 1.284 + image_width = w - 200; 1.285 + image_height = h - 150; 1.286 + set_zoom(); 1.287 + */ 1.288 +} 1.289 + 1.290 +void 1.291 +on_cropper_window_destroy(GtkObject* object, gpointer user_data) 1.292 +{ 1.293 + gtk_main_quit(); 1.294 +} 1.295 + 1.296 + 1.297 + 1.298 + 1.299 +gboolean 1.300 +on_key_press(GtkWidget* window, GdkEventKey* pKey, gpointer userdata) 1.301 +{ 1.302 + if (pKey->type != GDK_KEY_PRESS) { 1.303 + return FALSE; 1.304 + } 1.305 + switch (pKey->keyval) { 1.306 + case GDK_q: 1.307 + gtk_main_quit(); 1.308 + break; 1.309 + case GDK_Return: 1.310 + crop(); 1.311 + break; 1.312 + case GDK_plus: 1.313 + on_zoom_in_button_clicked(NULL, userdata); 1.314 + break; 1.315 + case GDK_minus: 1.316 + on_zoom_out_button_clicked(NULL, userdata); 1.317 + break; 1.318 + case GDK_0: 1.319 + on_zoom_100_button_clicked(NULL, userdata); 1.320 + break; 1.321 + case GDK_f: 1.322 + on_zoom_fit_button_clicked(NULL, userdata); 1.323 + break; 1.324 + } 1.325 + return TRUE; 1.326 +} 1.327 + 1.328 + 1.329 + 1.330 + 1.331 + 1.332 + 1.333 + 1.334 + 1.335 +int 1.336 +main(int argc, char* argv[]) 1.337 +{ 1.338 + /* commandline option handling */ 1.339 + if (argc != 2) { 1.340 + g_print("cropper -- a crop frontend to convert\n"); 1.341 + g_print("usage: cropper IMAGE\n"); 1.342 + return 1; 1.343 + } 1.344 + 1.345 + image_filename = argv[1]; 1.346 + gtk_init(&argc, &argv); 1.347 + 1.348 + cropper_window = create_cropper_window(); 1.349 + gtk_widget_show(cropper_window); 1.350 + gtk_main(); 1.351 + 1.352 + return 0; 1.353 +} 1.354 +