——————————pro———————————-
INCLUDEPATH += /usr/include/gtk-3.0 \
/usr/include/at-spi2-atk/2.0 \
/usr/include/at-spi-2.0 \
/usr/include/dbus-1.0 \
/usr/lib/x86_64-linux-gnu/dbus-1.0/include \
/usr/include/gtk-3.0 /usr/include/gio-unix-2.0 \
/usr/include/cairo /usr/include/pango-1.0 \
/usr/include/harfbuzz \
/usr/include/pango-1.0 \
/usr/include/fribidi \
/usr/include/harfbuzz \
/usr/include/atk-1.0 \
/usr/include/cairo \
/usr/include/pixman-1 \
/usr/include/uuid \
/usr/include/freetype2 \
/usr/include/gdk-pixbuf-2.0 \
/usr/include/libpng16 \
/usr/include/x86_64-linux-gnu \
/usr/include/libmount \
/usr/include/blkid \
/usr/include/glib-2.0 \
/usr/lib/x86_64-linux-gnu/glib-2.0/include\
/usr/include/
LIBS += -pthread \
-pthread \
-lgtk-3 \
-lgdk-3 \
-lpangocairo-1.0 \
-lpango-1.0 \
-lharfbuzz \
-latk-1.0 \
-lcairo-gobject \
-lcairo \
-lgdk_pixbuf-2.0 \
-lgio-2.0 \
-lgobject-2.0 \
-lglib-2.0 \
-lserialport
INCLUDEPATH += /home/yue/openCV/install/include\
/home/yue/openCV/install/include/opencv4 \
/home/yue/openCV/install/include/opencv2
LIBS += /home/yue/openCV/install/lib/libopencv_highgui.so \
/home/yue/openCV/install/lib/libopencv_core.so \
/home/yue/openCV/install/lib/libopencv_imgproc.so \
/home/yue/openCV/install/lib/libopencv_imgcodecs.so
SOURCES += \
main.cpp
—————————–main.cpp——————————
#include
#include
#include
#include
using namespace cv;
// 窗口中的图片位置和缩放比例
static int img_x = 100;
static int img_y = 100;
static double scale = 1.0;
static int start_x = 0;
static int start_y = 0;
static bool dragging = false;
static bool in_image = false;
static Mat bg_img;
static Mat fg_img;
// 检查鼠标是否在图片范围内
bool is_mouse_in_image(int mouse_x, int mouse_y) {
return (mouse_x >= img_x && mouse_x <= (img_x + fg_img.cols * scale) &&
mouse_y >= img_y && mouse_y <= (img_y + fg_img.rows * scale));
}
// 绘制图片到 GTK 窗口
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr) {
if (bg_img.empty() || fg_img.empty()) return FALSE;
// 将背景图像转换为 Cairo 图像
GdkPixbuf *bg_pixbuf = gdk_pixbuf_new_from_data(
(const guchar*)bg_img.data,
GDK_COLORSPACE_RGB,
false,
8,
bg_img.cols,
bg_img.rows,
bg_img.step,
NULL,
NULL
);
// 将前景图像转换为 Cairo 图像
GdkPixbuf *fg_pixbuf = gdk_pixbuf_new_from_data(
(const guchar*)fg_img.data,
GDK_COLORSPACE_RGB,
false,
8,
fg_img.cols,
fg_img.rows,
fg_img.step,
NULL,
NULL
);
// 绘制背景图像
gdk_cairo_set_source_pixbuf(cr, bg_pixbuf, 0, 0);
cairo_paint(cr);
// 绘制前景图像,应用缩放比例
cairo_translate(cr, img_x, img_y);
cairo_scale(cr, scale, scale);
gdk_cairo_set_source_pixbuf(cr, fg_pixbuf, 0, 0);
cairo_paint(cr);
g_object_unref(bg_pixbuf);
g_object_unref(fg_pixbuf);
return FALSE;
}
// 处理鼠标按下事件
static gboolean on_button_press_event(GtkWidget *widget, GdkEventButton *event) {
if (event->button == GDK_BUTTON_PRIMARY) {
if (in_image) {
dragging = true;
start_x = event->x – img_x;
start_y = event->y – img_y;
}
}
return FALSE;
}
// 处理鼠标释放事件
static gboolean on_button_release_event(GtkWidget *widget, GdkEventButton *event) {
if (event->button == GDK_BUTTON_PRIMARY) {
dragging = false;
}
return FALSE;
}
// 处理鼠标移动事件
static gboolean on_motion_notify_event(GtkWidget *widget, GdkEventMotion *event) {
if (dragging) {
// 计算新的位置
int new_img_x = event->x – start_x;
int new_img_y = event->y – start_y;
// 限制图片B在背景图片A的范围内
new_img_x = std::max(0, std::min(new_img_x, bg_img.cols – static_cast
new_img_y = std::max(0, std::min(new_img_y, bg_img.rows – static_cast
img_x = new_img_x;
img_y = new_img_y;
gtk_widget_queue_draw(widget); // 触发重绘
} else {
in_image = is_mouse_in_image(event->x, event->y);
}
return FALSE;
}
// 缩放图片B
static void on_zoom_in(GtkWidget *widget, gpointer data) {
scale += 0.1;
gtk_widget_queue_draw(GTK_WIDGET(data));
}
static void on_zoom_out(GtkWidget *widget, gpointer data) {
scale = std::max(0.1, scale – 0.1);
gtk_widget_queue_draw(GTK_WIDGET(data));
}
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
// 加载背景图片
bg_img = imread(“/home/yue/xy.jpg”, IMREAD_COLOR);
if (bg_img.empty()) {
g_print(“Failed to load background image\n”);
return -1;
}
// 加载前景图片
fg_img = imread(“/home/yue/monkey.png”, IMREAD_COLOR);
if (fg_img.empty()) {
g_print(“Failed to load foreground image\n”);
return -1;
}
// 创建 GTK 窗口
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
GtkWidget *drawing_area = gtk_drawing_area_new();
GtkWidget *zoom_in_button = gtk_button_new_with_label(“Zoom In”);
GtkWidget *zoom_out_button = gtk_button_new_with_label(“Zoom Out”);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), zoom_in_button, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), zoom_out_button, FALSE, FALSE, 0);
gtk_widget_set_size_request(drawing_area, bg_img.cols, bg_img.rows);
// 连接绘制事件
g_signal_connect(G_OBJECT(drawing_area), “draw”, G_CALLBACK(on_draw_event), NULL);
// 连接鼠标事件
g_signal_connect(G_OBJECT(drawing_area), “button-press-event”, G_CALLBACK(on_button_press_event), NULL);
g_signal_connect(G_OBJECT(drawing_area), “button-release-event”, G_CALLBACK(on_button_release_event), NULL);
g_signal_connect(G_OBJECT(drawing_area), “motion-notify-event”, G_CALLBACK(on_motion_notify_event), NULL);
gtk_widget_add_events(drawing_area, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
// 连接缩放按钮事件
g_signal_connect(G_OBJECT(zoom_in_button), “clicked”, G_CALLBACK(on_zoom_in), drawing_area);
g_signal_connect(G_OBJECT(zoom_out_button), “clicked”, G_CALLBACK(on_zoom_out), drawing_area);
g_signal_connect(window, “destroy”, G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}