diff --git a/Code/VisuRefac/otbChangeExtractRegionActionHandler.h b/Code/VisuRefac/otbChangeExtractRegionActionHandler.h
index eb3ed7adc88dc1705a7a9a79c48462d7db025493..b9fbef72a9a2e664d69219f8a19eff4d92b3e51a 100644
--- a/Code/VisuRefac/otbChangeExtractRegionActionHandler.h
+++ b/Code/VisuRefac/otbChangeExtractRegionActionHandler.h
@@ -70,11 +70,20 @@ public:
 	{
 	otbMsgDevMacro(<<"ChangeExtractRegionActionHandler::HandleWidgetEvent(): handling ("<<widgetId<<", "<<event<<")");
 	// Get the clicked index
+	typename ViewType::ImageWidgetType::PointType screenPoint, imagePoint;
+	screenPoint[0] = Fl::event_x();
+	screenPoint[1] = Fl::event_y();
+
+	// Transform to image point
+	imagePoint = m_View->GetScrollWidget()->GetScreenToImageTransform()->TransformPoint(screenPoint);
+
+	// Transform to index
 	typename ViewType::IndexType index;
-	index[0] = Fl::event_x();
-	index[1] = Fl::event_y();
+	index[0]=static_cast<int>(imagePoint[0]);
+	index[1]=static_cast<int>(imagePoint[1]);
+
 	// Change scaled extract region center
-	m_Model->SetExtractRegionCenter(m_View->GetScrollWidget()->ScreenIndexToImageIndex(index));
+	m_Model->SetExtractRegionCenter(index);
 	// Update model
 	m_Model->Update();
 	return true;
diff --git a/Code/VisuRefac/otbChangeScaledExtractRegionActionHandler.h b/Code/VisuRefac/otbChangeScaledExtractRegionActionHandler.h
index 1a43c0f9cfed36a530f9b01f206335d0d7a61a4f..ca019e0e39e528c9f5b0c9cbc5200e35e01baeee 100644
--- a/Code/VisuRefac/otbChangeScaledExtractRegionActionHandler.h
+++ b/Code/VisuRefac/otbChangeScaledExtractRegionActionHandler.h
@@ -70,11 +70,20 @@ public:
 	{
 	otbMsgDevMacro(<<"ChangeScaledExtractRegionActionHandler::HandleWidgetEvent(): handling ("<<widgetId<<", "<<event<<")");
 	// Get the clicked index
+	typename ViewType::ImageWidgetType::PointType screenPoint, imagePoint;
+	screenPoint[0] = Fl::event_x();
+	screenPoint[1] = Fl::event_y();
+
+	// Transform to image point
+	imagePoint = m_View->GetFullWidget()->GetScreenToImageTransform()->TransformPoint(screenPoint);
+
+	// Transform to index
 	typename ViewType::IndexType index;
-	index[0] = Fl::event_x();
-	index[1] = Fl::event_y();
+	index[0]=static_cast<int>(imagePoint[0]);
+	index[1]=static_cast<int>(imagePoint[1]);
+
 	// Change scaled extract region center
-	m_Model->SetScaledExtractRegionCenter(m_View->GetFullWidget()->ScreenIndexToRegionIndex(index));
+	m_Model->SetScaledExtractRegionCenter(index);
 	// Update model
 	m_Model->Update();
 	return true;
diff --git a/Code/VisuRefac/otbImageWidget.h b/Code/VisuRefac/otbImageWidget.h
index 676c54f0b31e4509ea72b66faee7290635761bd1..f596ae41ff6971037dfdf248ddeba7ebfb9fc1bb 100644
--- a/Code/VisuRefac/otbImageWidget.h
+++ b/Code/VisuRefac/otbImageWidget.h
@@ -24,6 +24,7 @@
 #include "otbImage.h"
 #include "itkRGBPixel.h"
 #include "itkFixedArray.h"
+#include "otbGlComponent.h"
 
 
 namespace otb
@@ -60,9 +61,15 @@ public:
   /** Region size & index typedef */
   typedef typename RegionType::SizeType       SizeType;
   typedef typename RegionType::IndexType      IndexType;
-
-  /** Color typedef (used to draw the rectangle, 4th channel is alpha) */
-  typedef typename Superclass::ColorType      ColorType;
+  
+  /** GlComponent typedef */
+  typedef GlComponent                                   GlComponentType;
+  typedef typename GlComponentType::Pointer             GlComponentPointerType;
+  typedef typename GlComponentType::ColorType           ColorType;     
+  typedef typename GlComponentType::AffineTransformType AffineTransformType;
+  typedef typename AffineTransformType::Pointer         AffineTransformPointerType;
+  typedef typename GlComponentType::VectorType          VectorType;
+  typedef typename GlComponentType::PointType           PointType;
 
   /** Reads the OpenGl buffer from an image pointer
    *  \param image The image pointer,
@@ -95,19 +102,9 @@ public:
   itkSetMacro(SubsamplingRate,unsigned int);
   itkGetMacro(SubsamplingRate,unsigned int);
 
-  /** Convert a screen index to a buffered region index */
-  IndexType ScreenIndexToRegionIndex(const IndexType& index );
-  
-  /** Convert a buffered region index to a screen index */
-  IndexType RegionIndexToScreenIndex(const IndexType& index);
-
-  /** Convert a screen index to an image index (taking into account
-   * subsampling rate) */
-  IndexType ScreenIndexToImageIndex(const IndexType& index );
-  
-  /** Convert an image index to a screen index (taking into account 
-   *  subsamplinh rate) */
-  IndexType ImageIndexToScreenIndex(const IndexType& index);
+  /** Get the image to screen transform */
+  itkGetObjectMacro(ImageToScreenTransform,AffineTransformType);
+  itkGetObjectMacro(ScreenToImageTransform,AffineTransformType);
 
 protected:
   /** Constructor */
@@ -120,9 +117,13 @@ protected:
   /** Actually render the buffer to the screen. This method is
     * used by FLTK routines and should not be called on its own.
     */
+
+  /** Update the image to screen transform */
+  void UpdateImageToScreenTransform();
+
   virtual void draw(void);
- 
-  /** Compute the linear buffer index according to the 2D region and
+
+   /** Compute the linear buffer index according to the 2D region and
    * its 2D index.This method is used when OTB_GL_USE_ACCEL is ON.
    * \param index 2D index
    * \param region 2D region
@@ -161,16 +162,16 @@ private:
   bool       m_DisplayRectangle;
   ColorType  m_RectangleColor;
   
-  /** Image extent coordinates in the display axis system */
-  double m_ImageExtentWidth;
-  double m_ImageExtentHeight;
-  double m_ImageExtentX;
-  double m_ImageExtentY;
+  /** The display extent */
+  RegionType m_Extent;
 
   /** If the image is subsampled with respect to the original image,
    * this indicates the subsampling rate */
   unsigned int m_SubsamplingRate;
 
+  /** Space to screen transform */
+  AffineTransformPointerType m_ImageToScreenTransform;
+  AffineTransformPointerType m_ScreenToImageTransform;
 
 }; // end class
 } // end namespace otb
diff --git a/Code/VisuRefac/otbImageWidget.txx b/Code/VisuRefac/otbImageWidget.txx
index bbe04276f97e6aa2b8b1fac0c04ad437cd27d6b6..86a431d98249cdc2c6b93801fe2aa2a1d91ce8cb 100644
--- a/Code/VisuRefac/otbImageWidget.txx
+++ b/Code/VisuRefac/otbImageWidget.txx
@@ -26,13 +26,17 @@ namespace otb
 template <class TInputImage>
 ImageWidget<TInputImage>
 ::ImageWidget() : m_IsotropicZoom(1.0), m_OpenGlBuffer(NULL), m_OpenGlBufferedRegion(),
-		 m_Rectangle(),m_DisplayRectangle(false),m_RectangleColor(), m_ImageExtentWidth(0),
-		  m_ImageExtentHeight(0), m_ImageExtentX(), m_ImageExtentY(), m_SubsamplingRate(1)
+		 m_Rectangle(),m_DisplayRectangle(false),m_RectangleColor(), m_Extent(), 
+		  m_SubsamplingRate(1), m_ImageToScreenTransform(),m_ScreenToImageTransform()
 {
   // Default color for rectangle
   m_RectangleColor.Fill(0.);
   m_RectangleColor[0]=1.0;
   m_RectangleColor[3]=1.0;
+  
+  // Initialize space to screen transform and inverse
+  m_ImageToScreenTransform = AffineTransformType::New();
+  m_ScreenToImageTransform = AffineTransformType::New();
 }
 
 template <class TInputImage>
@@ -120,6 +124,41 @@ ImageWidget<TInputImage>
   m_OpenGlBufferedRegion = region;
 }
 
+template <class TInputImage>
+void
+ImageWidget<TInputImage>
+::UpdateImageToScreenTransform()
+{
+  assert(m_IsotropicZoom>0 && "Isotropic zoom should be non null positive.");
+
+  typename RegionType::IndexType index;
+  typename RegionType::SizeType  size;
+  // Update image extent
+  size[0]= static_cast<unsigned int>(m_IsotropicZoom*static_cast<double>(m_OpenGlBufferedRegion.GetSize()[0]));
+  size[1]= static_cast<unsigned int>(m_IsotropicZoom*static_cast<double>(m_OpenGlBufferedRegion.GetSize()[1]));
+  index[0] = (this->w()-size[0])/2;
+  index[1] = (this->h()-size[1])/2;
+  m_Extent.SetIndex(index);
+  m_Extent.SetSize(size);
+
+  // Image to screen matrix
+  typename AffineTransformType::MatrixType s2iMatrix;
+  s2iMatrix.Fill(0);
+  const double s2iSpacing =(m_SubsamplingRate)/m_IsotropicZoom;
+  s2iMatrix(0,0)=s2iSpacing;
+  s2iMatrix(1,1)=s2iSpacing;
+  m_ScreenToImageTransform->SetMatrix(s2iMatrix);
+
+  // Image to screen translation
+  typename AffineTransformType::OutputVectorType translation;
+  translation[0]= m_SubsamplingRate * (m_OpenGlBufferedRegion.GetIndex()[0]-m_Extent.GetIndex()[0]/m_IsotropicZoom);
+  translation[1]= m_SubsamplingRate * (m_OpenGlBufferedRegion.GetIndex()[0]-m_Extent.GetIndex()[0]/m_IsotropicZoom);
+  m_ScreenToImageTransform->SetTranslation(translation);
+
+  // Compute the inverse transform
+  m_ScreenToImageTransform->GetInverse(m_ImageToScreenTransform);
+}
+
 template <class TInputImage>
 void
 ImageWidget<TInputImage>
@@ -135,16 +174,14 @@ ImageWidget<TInputImage>
     return;
     }
 
-  // Image extent
-  m_ImageExtentWidth = m_IsotropicZoom*static_cast<double>(m_OpenGlBufferedRegion.GetSize()[0]);
-  m_ImageExtentHeight = m_IsotropicZoom*static_cast<double>(m_OpenGlBufferedRegion.GetSize()[1]);
-  m_ImageExtentX = (static_cast<double>(this->w())-m_ImageExtentWidth)/2;
-  m_ImageExtentY = (static_cast<double>(this->h())-m_ImageExtentHeight)/2;
+  // Update the space to screen transform
+  this->UpdateImageToScreenTransform();
+
 
   if(!this->GetUseGlAcceleration())
     {
     // Set the pixel Zoom
-    glRasterPos2f(m_ImageExtentX,m_ImageExtentY);
+    glRasterPos2f(m_Extent.GetIndex()[0],m_Extent.GetIndex()[1]);
     glPixelZoom(m_IsotropicZoom,m_IsotropicZoom);
 
     // display the image
@@ -167,90 +204,41 @@ ImageWidget<TInputImage>
     glBindTexture (GL_TEXTURE_2D, texture);
     glBegin (GL_QUADS);
     glTexCoord2f (0.0, 1.0);
-    glVertex3f (m_ImageExtentX,m_ImageExtentY, 0.0);
+    glVertex3f (m_Extent.GetIndex()[0],m_Extent.GetIndex()[1], 0.0);
     glTexCoord2f (1.0, 1.0);
-    glVertex3f (m_ImageExtentX+m_ImageExtentWidth, m_ImageExtentY, 0.0);
+    glVertex3f (m_Extent.GetIndex()[0]+m_Extent.GetSize()[0], m_Extent.GetIndex()[1], 0.0);
     glTexCoord2f (1.0, 0.0);
-    glVertex3f (m_ImageExtentX+m_ImageExtentWidth,m_ImageExtentY+m_ImageExtentHeight, 0.0);
+    glVertex3f (m_Extent.GetIndex()[0]+m_Extent.GetSize()[0],m_Extent.GetIndex()[1]+m_Extent.GetSize()[1], 0.0);
     glTexCoord2f (0.0, 0.0);
-    glVertex3f (m_ImageExtentX,m_ImageExtentY+m_ImageExtentHeight, 0.0);
+    glVertex3f (m_Extent.GetIndex()[0],m_Extent.GetIndex()[1]+m_Extent.GetSize()[1], 0.0);
     glEnd ();
     glDisable(GL_TEXTURE_2D);
     }
 
-  // Draw the rectangle if necessary
-  if(m_DisplayRectangle)
-    {
-    typename RegionType::IndexType index;
-    typename RegionType::SizeType  size;
-
-    index = m_Rectangle.GetIndex();
-    // UL left in image space is LR in opengl space, so we need to get
-    // the real upper left
-    index[1]+=m_Rectangle.GetSize()[1];
-    index = ImageIndexToScreenIndex(index);
+//   // Draw the rectangle if necessary
+//   if(m_DisplayRectangle)
+//     {
+//     typename RegionType::IndexType index;
+//     typename RegionType::SizeType  size;
+
+//     index = m_Rectangle.GetIndex();
+//     // UL left in image space is LR in opengl space, so we need to get
+//     // the real upper left
+//     index[1]+=m_Rectangle.GetSize()[1];
+//     index = ImageIndexToScreenIndex(index);
     
-    size[0]=  static_cast<unsigned int>(static_cast<double>(m_Rectangle.GetSize()[0]/m_SubsamplingRate)*m_IsotropicZoom);
-    size[1] = static_cast<unsigned int>(static_cast<double>(m_Rectangle.GetSize()[1]/m_SubsamplingRate)*m_IsotropicZoom);
+//     size[0]=  static_cast<unsigned int>(static_cast<double>(m_Rectangle.GetSize()[0]/m_SubsamplingRate)*m_IsotropicZoom);
+//     size[1] = static_cast<unsigned int>(static_cast<double>(m_Rectangle.GetSize()[1]/m_SubsamplingRate)*m_IsotropicZoom);
     
 
-    glEnable(GL_BLEND);
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);   
-    glColor4f(m_RectangleColor[0],m_RectangleColor[1],m_RectangleColor[2],m_RectangleColor[3]);
-    glBegin(GL_LINE_LOOP);
-    gl_rect(index[0],index[1],size[0],size[1]);
-    glEnd();
-    glDisable(GL_BLEND);
-    }
-}
-
-template <class TInputImage>
-typename ImageWidget<TInputImage>
-::IndexType
-ImageWidget<TInputImage>
-::ScreenIndexToRegionIndex(const IndexType & index)
-{
-  IndexType resp; 
-  resp[0] = static_cast<int>(m_OpenGlBufferedRegion.GetIndex()[0]+static_cast<double>(index[0]-m_ImageExtentX)/m_IsotropicZoom);
-  resp[1] = static_cast<int>(m_OpenGlBufferedRegion.GetIndex()[1]+static_cast<double>(index[1]-m_ImageExtentY)/m_IsotropicZoom);
-  return resp;
-}
-
-template <class TInputImage>
-typename ImageWidget<TInputImage>
-::IndexType
-ImageWidget<TInputImage>
-::ScreenIndexToImageIndex(const IndexType & index)
-{
-  IndexType resp = ScreenIndexToRegionIndex(index); 
-  resp[0]*=m_SubsamplingRate;
-  resp[1]*=m_SubsamplingRate;
-  return resp;
+//     glEnable(GL_BLEND);
+//     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);   
+//     glColor4f(m_RectangleColor[0],m_RectangleColor[1],m_RectangleColor[2],m_RectangleColor[3]);
+//     glBegin(GL_LINE_LOOP);
+//     gl_rect(index[0],index[1],size[0],size[1]);
+//     glEnd();
+//     glDisable(GL_BLEND);
+//     }
 }
-
-template <class TInputImage>
-typename ImageWidget<TInputImage>
-::IndexType
-ImageWidget<TInputImage>
-::RegionIndexToScreenIndex(const IndexType & index)
-{
-  IndexType resp;
-  resp[0]=static_cast<int>(m_ImageExtentX+(index[0]-m_OpenGlBufferedRegion.GetIndex()[0])*m_IsotropicZoom);
-  resp[1]=static_cast<int>(m_ImageExtentY+m_ImageExtentHeight-(index[1]-m_OpenGlBufferedRegion.GetIndex()[1])*m_IsotropicZoom);
-   return resp;
-}
-
-template <class TInputImage>
-typename ImageWidget<TInputImage>
-::IndexType
-ImageWidget<TInputImage>
-::ImageIndexToScreenIndex(const IndexType & index)
-{
-  IndexType resp;
-  resp[0]=static_cast<int>(m_ImageExtentX+(index[0]/m_SubsamplingRate-m_OpenGlBufferedRegion.GetIndex()[0])*m_IsotropicZoom);
-  resp[1]=static_cast<int>(m_ImageExtentY+m_ImageExtentHeight-(index[1]/m_SubsamplingRate-m_OpenGlBufferedRegion.GetIndex()[1])*m_IsotropicZoom);
-  return resp;
-}
-
 }
 #endif
diff --git a/Code/VisuRefac/otbPixelDescriptionActionHandler.h b/Code/VisuRefac/otbPixelDescriptionActionHandler.h
index 527b153b4400ef969600ef39d847522fd4e20075..05110e4aa45487e4b97858829c744ea1723cb31f 100644
--- a/Code/VisuRefac/otbPixelDescriptionActionHandler.h
+++ b/Code/VisuRefac/otbPixelDescriptionActionHandler.h
@@ -96,14 +96,22 @@ public:
 	  }
 	  case FL_MOVE:
 	  {
-	  // Get the hovered index
-	  IndexType index;
-	  index[0]=Fl::event_x();
-	  index[1]=Fl::event_y();
-	  // Convert to image index
-	  index = sourceWidget->ScreenIndexToImageIndex(index);
+	  // Get the clicked index
+	  typename ViewType::ImageWidgetType::PointType screenPoint, imagePoint;
+	  screenPoint[0] = Fl::event_x();
+	  screenPoint[1] = Fl::event_y();
+	  
+	  // Transform to image point
+	  imagePoint = sourceWidget->GetScreenToImageTransform()->TransformPoint(screenPoint);
+	  
+	  // Transform to index
+	  typename ViewType::IndexType index;
+	  index[0]=static_cast<int>(imagePoint[0]);
+	  index[1]=static_cast<int>(imagePoint[1]);
+	  
 	  // Communicate new index to model
 	  m_Model->UpdatePixelDescription(index);
+	  
 	  return true;
 	  break;
 	  }