egami
C++ Image Processing program
|
00001 #include <algorithm> 00002 #include <memory> 00003 #include <string> 00004 00005 #include <gtkmm/image.h> 00006 #include <gtkmm/dialog.h> 00007 #include <gtkmm/radiobutton.h> 00008 #include <gtkmm/messagedialog.h> 00009 #include <gtkmm/stock.h> 00010 00011 #include "../display_unit.hpp" 00012 #include "../processing_page.hpp" 00013 #include "../processing_unit.hpp" 00014 #include "../utils.hpp" 00015 00016 namespace{ 00017 class Config: public Gtk::Dialog { 00018 public: 00019 enum Mode {UNKNOW, R90, R180, R270}; 00020 Config(): q("Rotate clockwise by:"), r90("90 deg"), r180("180 deg"), r270("270 deg") { 00021 set_resizable(false); 00022 00023 Gtk::RadioButton::Group group = r90.get_group(); 00024 r180.set_group(group); 00025 r270.set_group(group); 00026 00027 get_vbox()->pack_start(q); 00028 get_vbox()->pack_start(r90); 00029 get_vbox()->pack_start(r180); 00030 get_vbox()->pack_start(r270); 00031 00032 r90.set_active(); 00033 00034 add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); 00035 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); 00036 00037 show_all_children(); 00038 } 00039 00040 Mode mode(){ 00041 if(r90.get_active()) 00042 return R90; 00043 else if(r180.get_active()) 00044 return R180; 00045 else if(r270.get_active()) 00046 return R270; 00047 else 00048 return UNKNOW; 00049 } 00050 00051 private: 00052 Gtk::Label q; 00053 Gtk::RadioButton r90, r180, r270; 00054 }; 00055 00056 Display_unit* impl(const Image_unit *in){ 00057 if(in->has_roi()){ 00058 Gtk::MessageDialog d("Can not apply Rotate to a region of interest."); 00059 d.run(); 00060 return nullptr; 00061 } 00062 00063 Config c; 00064 if(c.run()!=Gtk::RESPONSE_OK) 00065 return nullptr; 00066 c.hide(); 00067 00068 Image_unit *out=nullptr; 00069 if(c.mode()==Config::R180) 00070 out=new Image_unit(in, in->height(), in->width()); 00071 else if(c.mode()==Config::R90 || c.mode()==Config::R270) 00072 out=new Image_unit(in, in->width(), in->height()); 00073 else 00074 return nullptr; 00075 00076 for(unsigned y=0; y<out->height(); ++y) 00077 for(unsigned x=0; x<out->width(); ++x){ 00078 unsigned char red, green, blue; 00079 switch(c.mode()){ 00080 case Config::R90:{ 00081 red=in->red(in->width()-x-1, y); 00082 green=in->green(in->width()-x-1, y); 00083 blue=in->blue(in->width()-x-1, y); 00084 break; 00085 } case Config::R180:{ 00086 red=in->red(in->height()-y-1, in->width()-x-1); 00087 green=in->green(in->height()-y-1, in->width()-x-1); 00088 blue=in->blue(in->height()-y-1, in->width()-x-1); 00089 break; 00090 } case Config::R270:{ 00091 red=in->red(x, in->height()-y-1); 00092 green=in->green(x, in->height()-y-1); 00093 blue=in->blue(x, in->height()-y-1); 00094 break; 00095 } 00096 } 00097 out->red(y, x, red); 00098 out->green(y, x, green); 00099 out->blue(y, x, blue); 00100 } 00101 00102 return out; 00103 } 00104 } 00105 00106 namespace Processes{ 00107 void rotate(){ 00108 Gtk::Image icon(cmake_install_prefix+std::string("/share/egami/icons/rotate.png")); 00109 std::shared_ptr<Processing_unit> pu(new Processing_unit(Processing(&impl), "Rotate", icon, false)); 00110 Processing_page::add_unit_to_page("Reshape", pu); 00111 } 00112 }