From 8cbf46d78e70a9f678e8d4d65c1a4e2f61db4ea0 Mon Sep 17 00:00:00 2001 From: Stefan Jahn Date: Sat, 26 Nov 2022 02:44:45 +0100 Subject: [PATCH] Added zoom functionality in histogram --- histogram.cc | 89 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/histogram.cc b/histogram.cc index e576421..fab6b82 100644 --- a/histogram.cc +++ b/histogram.cc @@ -4,21 +4,32 @@ * *****************************************************************************************/ +#include + #include "simpleskycam.h" #include "histogram.h" #include "gui.h" #include "configuration.h" #include "video.h" +#define HISTOGRAM_WIDTH 256 +#define HISTOGRAM_MARGIN 16 GtkWidget *histogram_da = NULL; -int histogram[3][256]; // 6* hist_width min, max, min , max..... +int histogram[3][HISTOGRAM_WIDTH]; // 6* hist_width min, max, min , max..... int histogram_max; // max vlaue +int histogram_zoom_start = 0; // first zoom value +int histogram_zoom_stop = HISTOGRAM_WIDTH; // second zoom value +int histogram_x; // current mouse x-coordinate +int histogram_pressed_x; // window x-coordinate when pressing a button +int histogram_released_x; // window x-coordinate when releasing a button +int histogram_pressed = 0; // indicates button pressed or not +int histogram_zoomed = 0; // indicates zoom extern GtkBuilder *_builder_; // work around for threads void cb_histogramda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data) { - int clientw, clienth, px, py2; + int clientw, clienth, px, px2, py2; GdkRGBA color; char txt[255]; @@ -57,15 +68,29 @@ void cb_histogramda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer da } gdk_cairo_set_source_rgba(cr, &color); - for (int i = 0; i < 256; i++) { - px = 16 + ((clientw-32) * i) / 256; - py2 = (clienth-16) - ((clienth-32) * histogram[chan][i]) / histogram_max; + int histogram_width = histogram_zoom_stop - histogram_zoom_start; + for (int i = 0; i < histogram_width; i++) { + px = HISTOGRAM_MARGIN + ((clientw-HISTOGRAM_MARGIN*2) * i) / histogram_width; + py2 = (clienth-HISTOGRAM_MARGIN) - ((clienth-HISTOGRAM_MARGIN*2) * histogram[chan][histogram_zoom_start+i]) / histogram_max; if (i == 0) cairo_move_to(cr, px, py2); else cairo_line_to(cr, px, py2); } cairo_stroke(cr); + + if (histogram_pressed) { + if (histogram_pressed_x < histogram_x) { + px = histogram_pressed_x; + px2 = histogram_x; + } else { + px2 = histogram_pressed_x; + px = histogram_x; + } + cairo_set_source_rgba(cr, 0.5, 0.5, 0.5, 0.5); + cairo_rectangle (cr, px, 0, px2-px, clienth); + cairo_fill (cr); + } } // draw some text @@ -122,8 +147,8 @@ void histogram_update(VideoFrame *vf) { if (vf == NULL) return; if (vf->w <= 0 ) return; - for (chan = 0; chan < 3; chan++) for (i = 0; i < 256; i++) - histogram[chan][i] = 0; + // initialize histogram + memset (histogram, 0, sizeof(histogram)); for (i = 0, x = 0; x < vf->w; x++) { for (y = 0; y < vf->h; y++) { @@ -136,25 +161,61 @@ void histogram_update(VideoFrame *vf) { if (histogram_da) gdk_window_invalidate_rect(gtk_widget_get_window(histogram_da), NULL, true); - for (histogram_max = 0, chan = 0; chan < 3; chan++) for (i = 0; i < 256; i++) + for (histogram_max = 0, chan = 0; chan < 3; chan++) for (i = 0; i < HISTOGRAM_WIDTH; i++) if (histogram_max < histogram[chan][i]) histogram_max = histogram[chan][i]; }; void cb_histogramda_motion (GtkWidget *widget, GdkEvent *event, gpointer data) { -// printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); + if(!histogram_zoomed) { + histogram_x = (int)round(event->button.x); + } }; void cb_histogramda_btnpress (GtkWidget *widget, gpointer data) { - printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); + if (!histogram_zoomed) { + if (!histogram_pressed) { + histogram_pressed = 1; + histogram_pressed_x = histogram_x; + } + } else { + histogram_zoomed = 0; + histogram_zoom_start = 0; + histogram_zoom_stop = HISTOGRAM_WIDTH; + } }; void cb_histogramda_btnrelease (GtkWidget *widget, gpointer data) { - printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); + if (!histogram_zoomed) { + if (histogram_pressed) { + histogram_pressed = 0; + histogram_released_x = histogram_x; + histogram_zoomed = 1; + + // here we need to compute start/stop coordinates inside histogram + int clientw; + clientw = gtk_widget_get_allocated_width(histogram_da); + + // translate first coordinate + histogram_zoom_start = (histogram_pressed_x - HISTOGRAM_MARGIN) * HISTOGRAM_WIDTH / (clientw - HISTOGRAM_MARGIN*2); + if (histogram_zoom_start < 0) histogram_zoom_start = 0; + if (histogram_zoom_start > 256) histogram_zoom_start = 256; + + // translate second coordinate + histogram_zoom_stop = (histogram_released_x - HISTOGRAM_MARGIN) * HISTOGRAM_WIDTH / (clientw - HISTOGRAM_MARGIN*2) + 1; + // limit the values + if (histogram_zoom_stop < 0) histogram_zoom_stop = 0; + if (histogram_zoom_stop > 256) histogram_zoom_stop = 256; + + // exchange the values if necessary + if (histogram_zoom_start > histogram_zoom_stop) { + int t = histogram_zoom_start; + histogram_zoom_start = histogram_zoom_stop; + histogram_zoom_stop = t; + } + } + } }; - - -