From e1d59d5b71a2114b42f339e2ad3c03a66a94ecac Mon Sep 17 00:00:00 2001 From: daleclack Date: Mon, 27 Dec 2021 23:06:00 +0800 Subject: [PATCH] Add image Scale for gtk119 --- Gtkmm3/gtk119_imageviewer2/src/MyImage.cc | 73 ++++++++++++++++------- Gtkmm3/gtk119_imageviewer2/src/MyImage.hh | 6 ++ Gtkmm3/gtk119_imageviewer2/src/MyWin.cc | 9 ++- Gtkmm3/gtk119_imageviewer2/src/MyWin.hh | 1 + cairo_scale.py | 60 +++++++++++++++++++ 5 files changed, 125 insertions(+), 24 deletions(-) create mode 100644 cairo_scale.py diff --git a/Gtkmm3/gtk119_imageviewer2/src/MyImage.cc b/Gtkmm3/gtk119_imageviewer2/src/MyImage.cc index cfcab9e..a504dd8 100644 --- a/Gtkmm3/gtk119_imageviewer2/src/MyImage.cc +++ b/Gtkmm3/gtk119_imageviewer2/src/MyImage.cc @@ -1,42 +1,69 @@ #include "MyImage.hh" -MyImage::MyImage(){ - +MyImage::MyImage() +:scale_radio(1.0) +{ } -MyImage::~MyImage(){ - +MyImage::~MyImage() +{ } -bool MyImage::on_draw(const Cairo::RefPtr &cr){ - if(!image){ +bool MyImage::on_draw(const Cairo::RefPtr &cr) +{ + if (!image) + { return false; } - int width = image->get_width(); - int height = image->get_height(); + // Set the default size for drawing area + set_size_request(surface->get_width()*scale_radio, + surface->get_height()*scale_radio); - //Set the default size for drawing area - set_size_request(width,height); + cr->scale(scale_radio, scale_radio); + cr->set_source(surface, 0, 0); - // Draw the image in the middle of the drawing area, or (if the image is - // larger than the drawing area) draw the middle part of the image. - Gdk::Cairo::set_source_pixbuf(cr, image, - (width - image->get_width())/2, (height - image->get_height())/2); - cr->paint(); return true; } -void MyImage::set_pixbuf(const Glib::RefPtr &pixbuf) +void MyImage::scale_draw(double scale) { - if(image){ - image.reset(); - } - - image = pixbuf; - - //ReDraw the draw area + // Set the scale radio and scale + scale_radio = scale; + queue_draw(); +} + +void MyImage::set_pixbuf(const Glib::RefPtr &pixbuf) +{ + if (image) + { + image.reset(); + } + + image = pixbuf; + + if (!surface) + { + // Create a surface + surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, + image->get_width(), image->get_height()); + } + else + { + } + + //Get Image Size + int width = image->get_width(); + int height = image->get_height(); + // Draw the image in the middle of the surface, or (if the image is + // larger than the drawing area) draw the middle part of the image. + auto cr = Cairo::Context::create(surface); + Gdk::Cairo::set_source_pixbuf(cr, image, + (width - image->get_width()) / 2, (height - image->get_height()) / 2); + cr->paint(); + + // ReDraw the draw area queue_draw(); } diff --git a/Gtkmm3/gtk119_imageviewer2/src/MyImage.hh b/Gtkmm3/gtk119_imageviewer2/src/MyImage.hh index 21cd2e2..3c5bec9 100644 --- a/Gtkmm3/gtk119_imageviewer2/src/MyImage.hh +++ b/Gtkmm3/gtk119_imageviewer2/src/MyImage.hh @@ -6,8 +6,14 @@ class MyImage : public Gtk::DrawingArea{ public: MyImage(); virtual ~MyImage(); + //Set a Pixbuf to draw void set_pixbuf(const Glib::RefPtr &pixbuf); + //Scale the image + void scale_draw(double scale); protected: bool on_draw(const Cairo::RefPtr &cr) override; + private: + double scale_radio; + Cairo::RefPtr surface; Glib::RefPtr image; }; diff --git a/Gtkmm3/gtk119_imageviewer2/src/MyWin.cc b/Gtkmm3/gtk119_imageviewer2/src/MyWin.cc index 354d3a4..1fd86e8 100644 --- a/Gtkmm3/gtk119_imageviewer2/src/MyWin.cc +++ b/Gtkmm3/gtk119_imageviewer2/src/MyWin.cc @@ -18,6 +18,7 @@ btnopen("Open Image") m_adjustment = Gtk::Adjustment::create(1.0,0.1,10.0,0.1,0.1); scale.set_default_direction(Gtk::TEXT_DIR_LTR); scale.set_adjustment(m_adjustment); + scale.signal_value_changed().connect(sigc::mem_fun(*this,&MyWin::scale_changed)); //Add control widgets btnbox.pack_start(scale); @@ -49,4 +50,10 @@ void MyWin::dialog_response(int response_id){ } dialog.reset(); -} +} + +void MyWin::scale_changed(){ + double value = scale.get_value(); + g_print("%f\n",value); + image_area.scale_draw(value); +} diff --git a/Gtkmm3/gtk119_imageviewer2/src/MyWin.hh b/Gtkmm3/gtk119_imageviewer2/src/MyWin.hh index 3f8d2fc..f9f6c80 100644 --- a/Gtkmm3/gtk119_imageviewer2/src/MyWin.hh +++ b/Gtkmm3/gtk119_imageviewer2/src/MyWin.hh @@ -21,4 +21,5 @@ class MyWin : public Gtk::Window{ //Signal Handlers void btnopen_clicked(); void dialog_response(int response_id); + void scale_changed(); }; diff --git a/cairo_scale.py b/cairo_scale.py new file mode 100644 index 0000000..f6bec1b --- /dev/null +++ b/cairo_scale.py @@ -0,0 +1,60 @@ +#!/usr/bin/python3 + +import cairo +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk + + +def draw(da, ctx): + global surface + + ctx.scale(scale, scale) + ctx.set_source_surface(surface) + ctx.get_source().set_filter(cairo.FILTER_NEAREST) + ctx.paint() + + da.set_size_request(surface.get_width() * scale, surface.get_height() * scale) + +def clicked(btn): + global scale + scale *= 1.5 + da = btn.get_parent().get_children()[1].get_child().get_child() + da.queue_draw() + + +def main(): + global scale + scale = 1 + + global surface + surface = cairo.ImageSurface.create_from_png("../Xe-Project/Gift.png") + + win = Gtk.Window() + win.connect('destroy', lambda w: Gtk.main_quit()) + win.set_default_size(500, 500) + + box = Gtk.Box() + win.add(box) + + btn = Gtk.Button() + btn.set_label("Scale") + box.add(btn) + btn.connect('clicked', clicked) + + scrolled_win = Gtk.ScrolledWindow() + box.add(scrolled_win) + + drawingarea = Gtk.DrawingArea() + drawingarea.set_vexpand(True) + drawingarea.set_hexpand(True) + scrolled_win.add(drawingarea) + drawingarea.connect('draw', draw) + + + win.show_all() + Gtk.main() + + +if __name__ == '__main__': + main() \ No newline at end of file