#include "sopnamsp.h" #include "machdefs.h" #include #include #include #include #include #include #include #include "piacmd.h" #include "nobjmgr.h" #include "pistdimgapp.h" #include "servnobjm.h" #include "picmap.h" #include "srandgen.h" #include "imgmag_pi.h" //--- Pour WidgetToImgMag() #include #include #include //----------------------------------------------------------------------- // Module chargeable de gestion d'images (jpeg,gif...) dans piapp // Ce module utilise la librairie ImageMagick // Declaration de la fonction d'activation et de desactivation du module extern "C" { void imgmagmod_init(); void imgmagmod_end(); } // Fonction pour creer et remplir un ImgMagObj en copiant le contenu d'un widget ImgMagObj* WidgetToImgMag(PIWdg* wdg); // Une classe commande-executor, permettant d'enregistrer de // nouvelles commandes a piapp class imgmagmodExecutor : public CmdExecutor { public: imgmagmodExecutor(); virtual ~imgmagmodExecutor(); // Execute s'occupe de l'execution effective des commandes virtual int Execute(string& keyw, vector& args, string& toks); }; /* --Methode-- */ imgmagmodExecutor::imgmagmodExecutor() { PIACmd * mpiac; NamedObjMgr omg; mpiac = omg.GetImgApp()->CmdInterpreter(); // On enregistre deux nouvelles commandes string hgrp = "ImageMagick"; // commande readphoto string kw = "readphoto"; string usage = "readphoto: Read an image file (jpeg/gif ...) \n" ; usage += "An object of type ImgMagObj (wrapper for Magick::Image) is \n"; usage += "created and managed by the NamedObjMgr\n"; usage += " Usage: readphoto ImageFileName \n"; usage += " See also writephoto \n"; mpiac->RegisterCommand(kw, usage, this, hgrp); // commande pirgb_rdphoto kw = "pirgb_rdphoto"; usage = "pirgb_rdphoto: Read an PI_RGB file (.rgb) into a ImgMagObj object\n" ; usage += " Usage: pirgb_rdphoto PI_RGB_FileName \n"; usage += " See also readphoto \n"; mpiac->RegisterCommand(kw, usage, this, hgrp); // commande writephoto kw = "writephoto"; usage = "writephoto: Save an ImgMagObj object to an image file (jpeg/gif ...) \n" ; usage += " Usage: writephoto ObjName OutFileName \n"; usage += " - ObjName : ImgMagObj object name \n"; usage += " - OutFileName : .jpg .gif .tiff output filename \n"; usage += " See also readphoto pirgb_wrphoto"; mpiac->RegisterCommand(kw, usage, this, hgrp); // commande pirgb_wrphoto kw = "pirgb_wrphoto"; usage = "pirgb_wrphoto: Save an ImgMagObj object to a PI_RGB file (.rgb) \n" ; usage += " Usage: pirgb_wrphoto ObjName OutFileName \n"; usage += " See also writephoto "; mpiac->RegisterCommand(kw, usage, this, hgrp); // commande wdg2imgfile win2imgfile kw = "wdg2imgfile"; usage = "wdg2imgfile: Save current widget to image file \n" ; usage += " Usage: wdg2imgfile OutFileName \n"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "win2imgfile"; usage = "win2imgfile: Save current window to image file \n" ; usage += " Usage: win2imgfile OutFileName \n"; mpiac->RegisterCommand(kw, usage, this, hgrp); } /* --Methode-- */ imgmagmodExecutor::~imgmagmodExecutor() { } /* --Methode-- */ int imgmagmodExecutor::Execute(string& kw, vector& tokens, string&) { NamedObjMgr omg; if ((kw=="readphoto") || (kw=="pirgb_rdphoto")) { if (tokens.size() < 1) { cout << "Usage: readphoto/pirgb_rdphoto FileName" << endl; return(0); } cout << " readphoto: reading file: " << tokens[0] << endl; Services2NObjMgr* serv = omg.GetServiceObj(); string objname = serv->FileName2Name(tokens[0]); ImgMagObj* img = NULL; if (kw=="readphoto") img = new ImgMagObj(tokens[0]); else { PIPixRGBArray rgbimg(tokens[0].c_str()); img = new ImgMagObj(rgbimg); } if (img != NULL) omg.AddObj(img, objname); } else if ((kw=="writephoto") || (kw=="pirgb_wrphoto")) { if (tokens.size() < 2) { cout << "Usage: writephoto/pirgb_wrphoto ObjName OutFileName" << endl; return(0); } AnyDataObj* obj=omg.GetObj(tokens[0]); if (obj == NULL) { cout << " No object with name " << tokens[0] << endl; return 1; } ImgMagObj* img = dynamic_cast(obj); if (img == NULL) { cout << " Object with name " << tokens[0] << " Not an ImgMagObj object" << endl; return 2; } if (kw=="writephoto") { cout << " writephoto: saving" << tokens[0] << " to file " << tokens[1] << endl; img->write(tokens[1]); return 0; } else if (kw=="pirgb_wrphoto") { cout << " pirgb_wrphoto: saving" << tokens[0] << " to PI_RGB file " << tokens[1] << endl; PIPixRGBArray rgba(0,0); img->FillPIRGBArray(rgba); rgba.SaveToFile(tokens[1].c_str()); return 0; } } else if ((kw=="wdg2imgfile")||(kw=="win2imgfile")) { if (tokens.size() < 1) { cout << "Usage: wdg2imgfile/win2imgfile FileName" << endl; return(0); } PIWdg* wdg = NULL; if (kw=="wdg2imgfile") wdg = (PIWdg *)omg.GetImgApp()->CurrentBaseWdg(); else wdg = (PIWdg *)omg.GetImgApp()->CurrentWindow(); if (wdg == NULL) { cout << " wdg2imgfile/win2imgfile: No current window/widget " << endl; return 1; } ImgMagObj* img = WidgetToImgMag(wdg); if (img) { cout << " wdg2imgfile : saving current widget to file " << tokens[0] << endl; img->write(tokens[0]); } return 0; } return(0); } static imgmagmodExecutor * imgmagex = NULL; static PIColorMap * cmap32768 = NULL; /* Nouvelle-Fonction */ void imgmagmod_init() { // Fonction d'initialisation du module cout << " imgmagmod_init() : Initializing ImageMagick interface piapp-module ..." << endl; // Appele par le gestionnaire de modules de piapp (PIACmd::LoadModule()) if (imgmagex) delete imgmagex; imgmagex = new imgmagmodExecutor; NamedObjMgr omg; // On alloue la grosse table de couleur avec 32768 couleurs RGB ... if (cmap32768 == NULL) { omg.GetImgApp()->LockMutex(); cmap32768 = new PIColorMap(CMAP_RGB32768); // cmap32768 = new PIColorMap(CMAP_RGB4096); omg.GetImgApp()->UnlockMutex(true); } Services2NObjMgr* serv = omg.GetServiceObj(); serv->RegisterClass(new ImgMagObj, new NOMAdapter_ImgMag ); cout << " imgmagmod_init() : Initialization OK " << endl; } /* Nouvelle-Fonction */ void imgmagmod_end() { // Desactivation du module if (imgmagex) delete imgmagex; imgmagex = NULL; NamedObjMgr omg; omg.GetImgApp()->CkEvt_LockMutex(); if (cmap32768) delete cmap32768; omg.GetImgApp()->UnlockMutex(true); cmap32768 = NULL; } inline void _col2fcol_(unsigned long & col, unsigned long & fcol) { if (col > 0x00FFFFFF) fcol = 0x01000000; else if (col > 0x0000FFFF) fcol = 0x000010000; else if (col > 0x000000FF) fcol = 0x00000100; else fcol = 1; //DBG cout << " _col2fcol_ col= " << col << " fcol=" << fcol << " ->" << col/fcol << endl; //DBG cout << " HEX _col2fcol_ col= " << hex << col << " fcol=" << fcol << " ->" << col/fcol << dec << endl; } /* Nouvelle-Fonction */ ImgMagObj* WidgetToImgMag(PIWdg* wdg) { if (wdg == NULL) { cout << " WidgetToImgMag() wdg=NULL " << endl; return NULL; } //DBG cout << "------ WidgetToImgMag() ------" << endl; NamedObjMgr omg; omg.GetImgApp()->CkEvt_LockMutex(); Display* mdsp = PIXDisplay(); int scr = XDefaultScreen(mdsp); int depth = DefaultDepth(mdsp,scr); Window xw = XtWindow(wdg->XtWdg()); unsigned long plane_mask = ~0; // tous les bits a 1 XImage * ximg = XGetImage(mdsp, xw, 0, 0, wdg->XSize(), wdg->YSize(), plane_mask, ZPixmap); //DBG cout << " Resultat XGetImage -> " << hex << ximg << dec << endl; if (ximg == NULL) return NULL; unsigned long red,green,blue; unsigned long fred,fgreen,fblue; XColor col; Colormap cmap = XDefaultColormap (mdsp, scr); red = 0x000000FF; green = 0x0000FF00; blue = 0x00FF0000; unsigned short maxrgb = ~0; col.red = maxrgb; col.green = col.blue = 0; if (XAllocColor(mdsp, cmap, &col)) { //DBG cout << " --DBG red-color , R,G,B=" << hex << col.red << "," << col.green << "," // << col.blue << " -> pixel=" << col.pixel << dec << endl; red = col.pixel; } col.green = maxrgb; col.red = col.blue = 0; if (XAllocColor(mdsp, cmap, &col)) { //DBG cout << " --DBG green-color , R,G,B=" << hex << col.red << "," << col.green << "," // << col.blue << " -> pixel=" << col.pixel << dec << endl; green = col.pixel; } col.blue = maxrgb; col.red = col.green = 0; if (XAllocColor(mdsp, cmap, &col)) { //DBG cout << " --DBG blue-color , R,G,B=" << hex << col.red << "," << col.green << "," // << col.blue << " -> pixel=" << col.pixel << dec << endl; blue = col.pixel; } _col2fcol_(red, fred); _col2fcol_(green, fgreen); _col2fcol_(blue, fblue); ImgMagObj* img = new ImgMagObj(wdg->XSize(), wdg->YSize()); Magick::ColorRGB rgb; int errcnt[3] = {0,0,0}; int errcnt2[3] = {0,0,0}; unsigned long pixel; for(int j=0; jYSize(); j++) for(int i=0; iXSize(); i++) { pixel = XGetPixel(ximg, i, j); double xcc[3]; xcc[0] = (double)((pixel&red)/fred)/255.; xcc[1] = (double)((pixel&green)/fgreen)/255.; xcc[2] = (double)((pixel&blue)/fblue)/255.; // Il faut proteger contre <0 et >1 sinon exception ImageMagck ! for(int kk=0; kk<3;kk++) { if (xcc[kk]<=0.) { xcc[kk] = 0.; errcnt[kk]++; } if (xcc[kk]>=1.) { xcc[kk] = 1.; errcnt2[kk]++; } } Magick::ColorRGB mcol(xcc[0], xcc[1], xcc[2]); // Magick::ColorRGB mcol(0.5+0.2*frandpm1(), 0.5+0.35*frandpm1(), 0.6+0.2*frandpm1()); img->pixelColor(i,j,mcol); } /* for(int kk=0; kk<3;kk++) cout << " ErrCnt k=" << kk << " : " << errcnt[kk] << "," << errcnt2[kk] << endl; */ XDestroyImage(ximg); omg.GetImgApp()->UnlockMutex(true); return img; }