Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ZoomImageCanvas.cpp
1 #include "ZoomImageCanvas.hh"
2 
3 #include <Gui/StringConv.hh>
4 
5 using namespace BIAS;
6 using namespace std;
7 
9 ZoomImageCanvas(wxWindow* parent, wxStatusBar *sbar,
10  int sbarid, wxWindowID id, const wxPoint& pos,
11  const wxSize& size, long style,
12  const wxString& name)
13  : wxPanel(parent, id, pos, size, style, name)
14 {
15  Bitmap_=NULL;
16  wximage_ = NULL;
17 
18  ZoomFactor_=10;
19  ZoomX_=0;
20  ZoomY_=0;
21  SBar_=sbar;
22  SBarID_=sbarid;
23  mousex_=mousey_=-1;
24  ClearDrawingContext_ = true;
25  ZoomXPos_ = ZoomYPos_ = 0;
26  wwidth_ = wheight_ = 0;
27 }
28 
29 
32 {
33  if (wximage_) { delete wximage_; wximage_=NULL; }
34  if (Bitmap_) { delete Bitmap_; Bitmap_=NULL; }
35 }
36 
37 
40 {
41 #ifndef UNIX
42 #ifdef __APPLE__
43  if (wwidth_==0 || wheight_==0){
44 #endif
45  GetSize(&wwidth_, &wheight_);
48 #ifdef __APPLE__
49  }
50 #endif
51 #endif //WIN32
52 
53 
54 
55  if (zim_.GetWidth()!=(unsigned)wwidth_ ||
56  zim_.GetHeight()!=(unsigned)wheight_)
57  zim_.Release();
58  if (zim_.IsEmpty())
60 
61  zim_.FillImageWithConstValue((unsigned char)0);
62  unsigned char **ida = zim_.GetImageDataArray();
63  unsigned char **sida= ucim_.GetImageDataArray();
64  int xsize=wwidth_/ZoomFactor_/2+1;
65  int ysize=wheight_/ZoomFactor_/2+1;
66  register unsigned int xstart, ystart;
67  register unsigned char res[3];
68  unsigned width=ucim_.GetWidth(), height=ucim_.GetHeight();
69  int mx, my;
70 
71  //cout << "wwidth/wheight: "<<wwidth_<<"x"<<wheight_<<endl;
72  //cout << "width/height: "<<width<<"x"<<height<<endl;
73  //cout << "x "<<(int)ZoomX_-(int)xsize<<" - "<<(int)ZoomX_+(int)xsize<<endl;
74  //cout << "y "<<(int)ZoomY_-(int)ysize<<" - "<<(int)ZoomY_+(int)ysize<<endl;
75  for (int x=(int)ZoomX_-(int)xsize; x<=(int)ZoomX_+(int)xsize; x++){
76  for (int y=(int)ZoomY_-(int)ysize; y<=(int)ZoomY_+(int)ysize; y++){
77  if (x<0 || y<0 || x>=(int)width || y>=(int)height){
78  //cout <<"out of src range: "<< x << "x" <<y<<endl;
79  res[0]=res[1]=res[2]=0;
80  } else {
81  mx=3*x;
82  res[0]=sida[y][mx]; res[1]=sida[y][mx+1]; res[2]=sida[y][mx+2];
83  }
84  xstart = (x-(int)ZoomX_)*(int)ZoomFactor_+(int)ZoomXPos_;
85  ystart = (y-(int)ZoomY_)*(int)ZoomFactor_+(int)ZoomYPos_;
86  for (register int i=0; i<(int)ZoomFactor_; i++){
87  for (register int j=0; j<(int)ZoomFactor_; j++){
88  my=ystart+i; mx=(xstart+j);
89  if (mx>=0 && my>=0 && mx<wwidth_ && my<wheight_){
90  mx*=3;
91  ida[my][mx] = res[0];
92  ida[my][mx+1] = res[1];
93  ida[my][mx+2] = res[2];
94  }
95  }
96  }
97  }
98  }
99  wxbitmap_mutex_.Lock();
100  if (wximage_) { delete wximage_; wximage_=NULL; }
101  wximage_ = new wxImage(zim_.GetWidth(), zim_.GetHeight(),
102  zim_.GetImageData(), true);
103  wxbitmap_mutex_.Unlock();
104  if (mousex_>=0 && mousey_>=0){
105  UpdateStatusBar((unsigned) mousex_, (unsigned) mousey_);
106  }
107 }
108 
110 UpdateStatusBar(unsigned mouseX, unsigned mouseY)
111 {
112  if(SBar_ == NULL)
113  return;
114  if(Bitmap_==NULL)
115  return;
116 
117  // compute original coordinate for zoomed canvas
118  int ix=(int)mouseX-(int)ZoomXPos_;
119  int iy=(int)mouseY-(int)ZoomYPos_;
120  if (ix<0)
121  ix=ix/(int)ZoomFactor_+(int)ZoomX_-1;
122  else
123  ix=ix/(int)ZoomFactor_+(int)ZoomX_;
124 
125  if (iy<0)
126  iy=iy/(int)ZoomFactor_+(int)ZoomY_-1;
127  else
128  iy=iy/(int)ZoomFactor_+(int)ZoomY_;
129 
130  //BIAS_MUTEX_LOCK(wxbitmap_mutex_);
131  origim_mutex_.Lock();
132 
133  {
134  if(ix>=0 && ix<(int)origim_.GetWidth()
135  && iy>=0 && iy<(int)origim_.GetHeight())
136  {
137  //wxbitmap_mutex_.Unlock();
138 
139  ostringstream os;
140  //display coordinate:
141  os << "("<<setw(3)<<ix<<", "<<setw(3)<<iy<<") : (";
142 
143  // determine pixel type relying on storage type
144  // dynamic_check to BIAS::Image<T> does not work because base image is
145  // loaded
146  {
147  for (unsigned int channel=0;
148  channel<origim_.GetChannelCount();
149  channel++){
150  if (channel!=0)
151  os <<","; // no comma before first value
152  BIAS::ImageBase::PrintPixelValue(origim_, ix,iy, (unsigned short)channel, os );
153  }
154  }
155  os <<")";
156  SBar_->SetStatusText(AsciiToWx(os.str()), SBarID_);
157  };
158  }
159  origim_mutex_.Unlock();
160  //wxbitmap_mutex_.Unlock();
161 }
162 
163 
166 {
167  origim_mutex_.Lock();
168  origim_ = im;
169  origim_mutex_.Unlock();
170  ucim_ = ucim;
171  GetZoomImage();
172 #ifdef WIN32
173  this->Refresh();
174 #else
175  wxPaintEvent pe;
176  wxPostEvent(this->GetEventHandler(),pe);
177 #endif
178 }
179 
180 
182 NewCoo(unsigned x, unsigned y)
183 {
184  if (ZoomX_!=x || ZoomY_!=y){
185  ZoomX_=x;
186  ZoomY_=y;
189  GetZoomImage();
190 #ifdef WIN32
191  this->Refresh();
192 #else
193  wxPaintEvent pe;
194  wxPostEvent(this->GetEventHandler(),pe);
195 #endif
196  }
197 }
198 
199 
201 NewZoom(int zoom)
202 {
203  if ((unsigned)zoom!=ZoomFactor_){
204  ZoomFactor_=zoom;
205  GetZoomImage();
206 #ifdef WIN32
207  this->Refresh();
208 #else
209  wxPaintEvent pe;
210  wxPostEvent(this->GetEventHandler(),pe);
211 #endif
212  }
213 }
214 
215 
216 BEGIN_EVENT_TABLE (ZoomImageCanvas, wxWindow)
217 EVT_PAINT (ZoomImageCanvas::OnPaint)
218 EVT_MOTION (ZoomImageCanvas::OnMouseMove)
219 EVT_RIGHT_DOWN (ZoomImageCanvas::OnRightMouse)
220 EVT_LEFT_DOWN (ZoomImageCanvas::OnLeftMouse)
221 EVT_LEFT_DCLICK (ZoomImageCanvas::OnLeftMouseDoubleClicked)
222 EVT_CHAR (ZoomImageCanvas::OnKey)
223 EVT_SIZE (ZoomImageCanvas::OnResize)
224 EVT_LEAVE_WINDOW(ZoomImageCanvas::OnMouseLeave)
225 END_EVENT_TABLE()
226 
227 
228 void ZoomImageCanvas::
229 OnRightMouse(wxMouseEvent &event)
230 {
231  wxClientDC dc(this);
232  PrepareDC(dc);
233  wxPoint pos = event.GetPosition();
234  int x = dc.DeviceToLogicalX( pos.x );
235  int y = dc.DeviceToLogicalY( pos.y );
236  int ix=(x-(int)(wwidth_>>1))/(int)ZoomFactor_+(int)ZoomX_;
237  int iy=(y-(int)(wheight_>>1))/(int)ZoomFactor_+(int)ZoomY_;
238  //cerr << "new coo: "<<ix<<", "<<iy; cerr.flush();
239  NewCoo(ix, iy);
240  //cerr << " .... finished\n";
241 }
242 
243 //void ZoomImageCanvas::OnMouseLeave(wxMouseEvent &event)
245 OnMouseLeave(wxMouseEvent&)
246 {
247  if (SBar_){ SBar_->SetStatusText(wxT(""), SBarID_); }
248  mousex_=mousey_=-1;
249 }
250 
251 
253 OnResize(wxSizeEvent &event)
254 {
255  GetSize(&wwidth_, &wheight_);
258  GetZoomImage();
259  event.Skip();
260 #ifdef WIN32
261  this->Refresh();
262 #else
263  wxPaintEvent pe;
264  wxPostEvent(this->GetEventHandler(),pe);
265 #endif
266 }
267 
268 //void ZoomImageCanvas::OnPaint(wxPaintEvent & event)
270 OnPaint(wxPaintEvent & )
271 {
272  // wxPanel::OnPaint(event);
273 
274  wxBufferedPaintDC dc(this);
275  PrepareDC(dc);
276  wxMutexLocker locker(wxbitmap_mutex_);
277  if (wximage_ && wximage_->IsOk()){
278  if (Bitmap_ != NULL) {
279  delete Bitmap_; Bitmap_ = NULL;
280  }
281  Bitmap_ = new wxBitmap(*wximage_);
282  }
283  if (Bitmap_ && Bitmap_->IsOk() && dc.IsOk()) {
284  // since now using double buffering, turning of clearing is actually
285  // unnecessary
286  if (ClearDrawingContext_) {
287  dc.Clear();
288  }
289  dc.DrawBitmap(*Bitmap_, 0, 0);
290  }
291 }
292 
293 void ZoomImageCanvas::OnMouseMove(wxMouseEvent &event)
294 {
295  wxClientDC dc(this);
296  PrepareDC(dc);
297  wxPoint pos = event.GetPosition();
298  mousex_ = dc.DeviceToLogicalX( pos.x );
299  mousey_ = dc.DeviceToLogicalY( pos.y );
300  UpdateStatusBar((unsigned) mousex_, (unsigned) mousey_);
301 }
302 
303 
305 OnLeftMouse(wxMouseEvent &event)
306 {
307  // pass event through to ImageCanvas which is parent of parent
308  if (GetParent() && GetParent()->GetParent()){
309  wxClientDC dc(this);
310  PrepareDC(dc);
311  wxPoint pos = event.GetPosition();
312  unsigned int x = dc.DeviceToLogicalX( pos.x );
313  unsigned int y = dc.DeviceToLogicalY( pos.y );
314  int ix=(int)x-(int)ZoomXPos_, iy=(int)y-(int)ZoomYPos_;
315  if (ix<0) ix=ix/(int)ZoomFactor_+(int)ZoomX_-1;
316  else ix=ix/(int)ZoomFactor_+(int)ZoomX_;
317  if (iy<0) iy=iy/(int)ZoomFactor_+(int)ZoomY_-1;
318  else iy=iy/(int)ZoomFactor_+(int)ZoomY_;
319 
320  wxMouseEvent ke=event;
321  ke.m_x=ix;
322  ke.m_y=iy;
323  ke.SetId(GetParent()->GetParent()->GetId());
324  wxPostEvent(GetParent()->GetParent()->GetEventHandler(), ke);
325  //cerr << "passing mouse event at ("<<ix<<", "<<iy
326  // <<") from ZoomImageCanvas to ImageCanvas\n";
327  } else {
328  BIASERR("no ImageCanvas belonging to ZoomImageCanvas\n");
329  }
330  event.Skip();
331 }
332 
333 
335 OnLeftMouseDoubleClicked(wxMouseEvent &event)
336 {
337  // pass event through to ImageCanvas which is parent of parent
338  if (GetParent()){
339  // if (GetParent() && GetParent()->GetParent()){
340  wxClientDC dc(this);
341  PrepareDC(dc);
342  wxPoint pos = event.GetPosition();
343  unsigned int x = dc.DeviceToLogicalX( pos.x );
344  unsigned int y = dc.DeviceToLogicalY( pos.y );
345  int ix=(int)x-(int)ZoomXPos_, iy=(int)y-(int)ZoomYPos_;
346  if (ix<0) ix=ix/(int)ZoomFactor_+(int)ZoomX_-1;
347  else ix=ix/(int)ZoomFactor_+(int)ZoomX_;
348  if (iy<0) iy=iy/(int)ZoomFactor_+(int)ZoomY_-1;
349  else iy=iy/(int)ZoomFactor_+(int)ZoomY_;
350 
351  wxMouseEvent ke=event;
352  ke.m_x=ix;
353  ke.m_y=iy;
354  ke.SetId(GetParent()->GetParent()->GetId());
355  wxPostEvent(GetParent()->GetParent()->GetEventHandler(), ke);
356  //cerr << "passing mouse event at ("<<ix<<", "<<iy
357  // <<") from ZoomImageCanvas to ImageCanvas\n";
358  } else {
359  BIASERR("no ImageCanvas belonging to ZoomImageCanvas\n");
360  }
361  event.Skip();
362 }
363 
364 
366 OnKey(wxKeyEvent &event)
367 {
368  // pass event through to ImageCanvas which is parent of parent
369  if (GetParent()){
370  // if (GetParent() && GetParent()->GetParent()){
371  wxClientDC dc(this);
372  PrepareDC(dc);
373  wxPoint pos = event.GetPosition();
374  unsigned int x = dc.DeviceToLogicalX( pos.x );
375  unsigned int y = dc.DeviceToLogicalY( pos.y );
376  int ix=(int)x-(int)ZoomXPos_, iy=(int)y-(int)ZoomYPos_;
377  if (ix<0) ix=ix/(int)ZoomFactor_+(int)ZoomX_-1;
378  else ix=ix/(int)ZoomFactor_+(int)ZoomX_;
379  if (iy<0) iy=iy/(int)ZoomFactor_+(int)ZoomY_-1;
380  else iy=iy/(int)ZoomFactor_+(int)ZoomY_;
381 
382  wxKeyEvent ke=event;
383  ke.m_x=ix;
384  ke.m_y=iy;
385  ke.SetId(GetParent()->GetParent()->GetId());
386  ke.m_keyCode=event.GetKeyCode();
387  wxPostEvent(GetParent()->GetParent()->GetEventHandler(), ke);
388  // cerr << "passing KEY event at ("<<ix<<", "<<iy
389  // <<") from ZoomImageCanvas to ImageCanvas\n";
390  } else {
391  BIASERR("no ImageCanvas belonging to ZoomImageCanvas\n");
392  }
393  event.Skip();
394 }
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
void UpdateStatusBar(unsigned x, unsigned y)
wxString AsciiToWx(const char *thestring)
Converts a C string to a wxString.
Definition: StringConv.hh:32
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
void OnLeftMouseDoubleClicked(wxMouseEvent &event)
static void PrintPixelValue(const ImageBase &im, const unsigned int x, const unsigned int y, const unsigned short channel=0, std::ostream &os=std::cout)
print the (typed) pixel value to stream.
Definition: ImageBase.cpp:1919
BIAS::ImageBase origim_
void NewCoo(unsigned x, unsigned y)
void OnKey(wxKeyEvent &event)
BIAS::Image< unsigned char > zim_
unsigned int GetWidth() const
Definition: ImageBase.hh:312
void NewImage(BIAS::ImageBase &im, BIAS::Image< unsigned char > &ucim)
void OnMouseMove(wxMouseEvent &event)
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
unsigned int GetHeight() const
Definition: ImageBase.hh:319
void OnResize(wxSizeEvent &event)
void FillImageWithConstValue(StorageType Value)
fill grey images
Definition: Image.cpp:456
void OnMouseLeave(wxMouseEvent &event)
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
Definition: Image.hh:137
void OnPaint(wxPaintEvent &event)
ZoomImageCanvas(wxWindow *parent, wxStatusBar *sbar=NULL, int sbarid=0, wxWindowID id=-1, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(320, 240), long style=wxTAB_TRAVERSAL, const wxString &name=wxT("ZoomImageCanvas"))
BIAS::Image< unsigned char > ucim_
This is the base class for images in BIAS.
Definition: ImageBase.hh:102
void OnLeftMouse(wxMouseEvent &event)
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153