]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
draft image composer implementation
authorasl <asl@opencascade.com>
Tue, 2 Jul 2013 08:08:32 +0000 (08:08 +0000)
committerasl <asl@opencascade.com>
Tue, 2 Jul 2013 08:08:32 +0000 (08:08 +0000)
15 files changed:
src/ImageComposer/ImageComposer.h [new file with mode: 0644]
src/ImageComposer/ImageComposer_ColorMaskOperator.cxx [new file with mode: 0644]
src/ImageComposer/ImageComposer_ColorMaskOperator.h [new file with mode: 0644]
src/ImageComposer/ImageComposer_CropOperator.cxx [new file with mode: 0644]
src/ImageComposer/ImageComposer_CropOperator.h [new file with mode: 0644]
src/ImageComposer/ImageComposer_CutOperator.cxx [new file with mode: 0644]
src/ImageComposer/ImageComposer_CutOperator.h [new file with mode: 0644]
src/ImageComposer/ImageComposer_FuseOperator.cxx [new file with mode: 0644]
src/ImageComposer/ImageComposer_FuseOperator.h [new file with mode: 0644]
src/ImageComposer/ImageComposer_Image.cxx [new file with mode: 0644]
src/ImageComposer/ImageComposer_Image.h [new file with mode: 0644]
src/ImageComposer/ImageComposer_Operator.cxx [new file with mode: 0644]
src/ImageComposer/ImageComposer_Operator.h [new file with mode: 0644]
src/ImageComposer/ImageComposer_Tools.cxx [new file with mode: 0644]
src/ImageComposer/ImageComposer_Tools.h [new file with mode: 0644]

diff --git a/src/ImageComposer/ImageComposer.h b/src/ImageComposer/ImageComposer.h
new file mode 100644 (file)
index 0000000..c759c8f
--- /dev/null
@@ -0,0 +1,12 @@
+
+#ifdef WIN32
+
+  #ifdef IMAGECOMPOSER_EXPORTS
+    #define IMAGE_COMPOSER_API __declspec( dllexport )
+  #else
+    #define IMAGE_COMPOSER_API __declspec( dllimport )
+  #endif
+
+#else
+   #define IMAGE_COMPOSER_API 
+#endif
diff --git a/src/ImageComposer/ImageComposer_ColorMaskOperator.cxx b/src/ImageComposer/ImageComposer_ColorMaskOperator.cxx
new file mode 100644 (file)
index 0000000..b0ceddc
--- /dev/null
@@ -0,0 +1,86 @@
+
+#include <ImageComposer_ColorMaskOperator.h>
+#include <ImageComposer_Image.h>
+#include <QRectF>
+#include <QRgb>
+#include <QPixmap>
+#include <QPainter>
+
+/**
+  Constructor
+  @param theRefColor the color to the searched (the color for mask)
+  @param isMakeTransparent the boolean flag controlling if the pixels with matching color
+                           should be made transparent or one with non-matching color
+  @param theRGBThreshold the threshold for RGB components
+  @param theAlphaThreshold the threshold for Alpha component
+*/
+ImageComposer_ColorMaskOperator::ImageComposer_ColorMaskOperator( const QColor& theRefColor,
+                                                                  bool isMakeTransparent,
+                                                                  int theRGBThreshold,
+                                                                  int theAlphaThreshold )
+: ImageComposer_Operator( TRANSPARENT ),
+  myRefColor( theRefColor ), myIsMakeTransparent( isMakeTransparent ),
+  myRGBThreshold( theRGBThreshold ), myAlphaThreshold( theAlphaThreshold )
+{
+}
+
+/**
+*/
+ImageComposer_ColorMaskOperator::~ImageComposer_ColorMaskOperator()
+{
+}
+
+/**
+*/
+QString ImageComposer_ColorMaskOperator::name() const
+{
+  return "colormask";
+}
+
+/**
+*/
+QRectF ImageComposer_ColorMaskOperator::calcResultBoundingRect( const QRectF& theImage1Bounds, 
+                                                                const QRectF& ) const
+{
+  return theImage1Bounds;
+}
+
+/**
+*/
+void ImageComposer_ColorMaskOperator::drawResult( QPainter& thePainter,
+                                                  const ImageComposer_Image& theImage1,
+                                                  const ImageComposer_Image& ) const
+{
+  QImage anImage = theImage1.convertToFormat( QImage::Format_ARGB32 );
+  int aRMin = myRefColor.red()    - myRGBThreshold;
+  int aRMax = myRefColor.red()    + myRGBThreshold;
+  int aGMin = myRefColor.green()  - myRGBThreshold;
+  int aGMax = myRefColor.green()  + myRGBThreshold;
+  int aBMin = myRefColor.blue()   - myRGBThreshold;
+  int aBMax = myRefColor.blue()   + myRGBThreshold;
+  int anAMin = myRefColor.alpha() - myAlphaThreshold;
+  int anAMax = myRefColor.alpha() + myAlphaThreshold;
+
+  QRgb aTransparent = TRANSPARENT.rgba();
+
+  for( int y = 0, aMaxY = anImage.height(); y < aMaxY; y++ )
+    for( int x = 0, aMaxX = anImage.width(); x < aMaxX; x++ )
+    {
+      QRgb* aLine = ( QRgb* )anImage.scanLine( y );
+      int aRed    = qRed( aLine[x] );
+      int aGreen  = qGreen( aLine[x] );
+      int aBlue   = qBlue( aLine[x] );
+      int anAlpha = qAlpha( aLine[x] );
+      bool isInRange = ( anAMin <= anAlpha && anAlpha <= anAMax )
+                    && (  aRMin <= aRed    && aRed    <=  aRMax )
+                    && (  aGMin <= aGreen  && aGreen  <=  aGMax )
+                    && (  aBMin <= aBlue   && aBlue   <=  aBMax );
+      if( myIsMakeTransparent == isInRange )
+        aLine[x] = aTransparent;
+    }
+
+  ImageComposer_Image aResult;
+  aResult = anImage;
+  aResult.setTransform( theImage1.transform() );
+  aResult.draw( thePainter );
+}
diff --git a/src/ImageComposer/ImageComposer_ColorMaskOperator.h b/src/ImageComposer/ImageComposer_ColorMaskOperator.h
new file mode 100644 (file)
index 0000000..15b15aa
--- /dev/null
@@ -0,0 +1,37 @@
+
+#ifndef IMAGE_COMPOSER_COLOR_MASK_OPERATOR_HEADER
+#define IMAGE_COMPOSER_COLOR_MASK_OPERATOR_HEADER
+
+#include <ImageComposer_Operator.h>
+#include <QColor>
+
+/**
+  \class ImageComposer_ColorMaskOperator
+  Implementation of the color mask operator
+*/
+class IMAGE_COMPOSER_API ImageComposer_ColorMaskOperator : public ImageComposer_Operator
+{
+public:
+  ImageComposer_ColorMaskOperator( const QColor& theRefColor,
+                                   bool isMakeTransparent,
+                                   int theRGBThreshold,
+                                   int theAlphaThreshold );
+  virtual ~ImageComposer_ColorMaskOperator();
+
+  virtual QString name() const;
+
+protected:
+  virtual QRectF calcResultBoundingRect( const QRectF& theImage1Bounds, 
+                                         const QRectF& theImage2Bounds ) const;
+  virtual void drawResult( QPainter& thePainter, const ImageComposer_Image& theImage1,
+                                                 const ImageComposer_Image& theImage2 ) const;
+
+private:
+  QColor myRefColor;         ///< the color to the searched (the color for mask)
+  bool myIsMakeTransparent;  ///< the boolean flag controlling if the pixels with matching color
+                             ///< should be made transparent or one with non-matching color
+  int myRGBThreshold;        ///< the threshold for RGB components
+  int myAlphaThreshold;      ///< the threshold for Alpha component
+};
+
+#endif
diff --git a/src/ImageComposer/ImageComposer_CropOperator.cxx b/src/ImageComposer/ImageComposer_CropOperator.cxx
new file mode 100644 (file)
index 0000000..a1de875
--- /dev/null
@@ -0,0 +1,86 @@
+
+#include <ImageComposer_CropOperator.h>
+#include <ImageComposer_Image.h>
+#include <QPixmap>
+#include <QPainter>
+
+/**
+  Constructor
+  @param theBackground the background color for result image
+  @param theRect the cropping rectangle (in the global CS)
+*/
+ImageComposer_CropOperator::ImageComposer_CropOperator( const QColor& theBackground, const QRect& theRect )
+: ImageComposer_Operator( theBackground )
+{
+  myClipPath.addRect( theRect );
+}
+
+/**
+  Constructor
+  @param theBackground the background color for result image
+  @param thePath the cropping path (in the global CS)
+*/
+ImageComposer_CropOperator::ImageComposer_CropOperator( const QColor& theBackground, const QPainterPath& thePath )
+: ImageComposer_Operator( theBackground )
+{
+  myClipPath = thePath;
+}
+
+/**
+*/
+ImageComposer_CropOperator::~ImageComposer_CropOperator()
+{
+}
+
+/**
+  Return clipping path
+  @return clipping path
+*/
+QPainterPath ImageComposer_CropOperator::clipPath() const
+{
+  return myClipPath;
+}
+
+/**
+*/
+QString ImageComposer_CropOperator::name() const
+{
+  return "crop";
+}
+
+/**
+*/
+QRectF ImageComposer_CropOperator::calcResultBoundingRect( const QRectF&, const QRectF& ) const
+{
+  return myImgClipPath.boundingRect();
+}
+
+/**
+*/
+void ImageComposer_CropOperator::drawResult( QPainter& thePainter,
+                                             const ImageComposer_Image& theImage1,
+                                             const ImageComposer_Image& ) const
+{
+  QRectF aBounds = myImgClipPath.boundingRect();
+  QTransform aTranslate;
+  aTranslate.translate( -aBounds.left(), -aBounds.top() );
+  QPainterPath aClipPath = aTranslate.map( myImgClipPath );
+  thePainter.setClipPath( aClipPath );
+  theImage1.draw( thePainter );
+  //thePainter.fillPath( aClipPath, Qt::red );
+}
+
+/**
+*/
+ImageComposer_Image ImageComposer_CropOperator::process( const ImageComposer_Image& theImage1,
+                                                         const ImageComposer_Image& theImage2 ) const
+{
+  QRect anImageRect( 0, 0, theImage1.width(), theImage1.height() );
+  QPainterPath anImageBoundsPath;
+  anImageBoundsPath.addPolygon( theImage1.transform().mapToPolygon( anImageRect ) );
+
+  const_cast<ImageComposer_CropOperator*>( this )->myImgClipPath =
+    theImage1.transform().inverted().map( myClipPath.intersected( anImageBoundsPath ) );
+
+  return ImageComposer_Operator::process( theImage1, theImage2 );
+}
diff --git a/src/ImageComposer/ImageComposer_CropOperator.h b/src/ImageComposer/ImageComposer_CropOperator.h
new file mode 100644 (file)
index 0000000..a359249
--- /dev/null
@@ -0,0 +1,37 @@
+
+#ifndef IMAGE_COMPOSER_CROP_OPERATOR_HEADER
+#define IMAGE_COMPOSER_CROP_OPERATOR_HEADER
+
+#include <ImageComposer_Operator.h>
+#include <QColor>
+#include <QPainterPath>
+
+/**
+  \class ImageComposer_CropOperator
+  Implementation of the cropping operator
+*/
+class IMAGE_COMPOSER_API ImageComposer_CropOperator : public ImageComposer_Operator
+{
+public:
+  ImageComposer_CropOperator( const QColor& theBackground, const QRect& );
+  ImageComposer_CropOperator( const QColor& theBackground, const QPainterPath& );
+  virtual ~ImageComposer_CropOperator();
+
+  QPainterPath clipPath() const;
+
+  virtual QString name() const;
+  virtual ImageComposer_Image process( const ImageComposer_Image& theImage1,
+                                       const ImageComposer_Image& theImage2 ) const;
+
+protected:
+  virtual QRectF calcResultBoundingRect( const QRectF& theImage1Bounds, 
+                                         const QRectF& theImage2Bounds ) const;
+  virtual void drawResult( QPainter& thePainter, const ImageComposer_Image& theImage1,
+                                                 const ImageComposer_Image& theImage2 ) const;
+
+private:
+  QPainterPath myClipPath;     ///< the clipping path specified initially
+  QPainterPath myImgClipPath;  ///< the clipping path mapped to first image's local CS
+};
+
+#endif
diff --git a/src/ImageComposer/ImageComposer_CutOperator.cxx b/src/ImageComposer/ImageComposer_CutOperator.cxx
new file mode 100644 (file)
index 0000000..f516235
--- /dev/null
@@ -0,0 +1,46 @@
+
+#include <ImageComposer_CutOperator.h>
+#include <ImageComposer_Image.h>
+#include <QString>
+#include <QPixmap>
+#include <QPainter>
+
+/**
+  Constructor
+  @param theBackground the background color for result image
+*/
+ImageComposer_CutOperator::ImageComposer_CutOperator( const QColor& theBackground )
+  : ImageComposer_Operator( theBackground )
+{
+}
+
+/**
+*/
+ImageComposer_CutOperator::~ImageComposer_CutOperator()
+{
+}
+
+/**
+*/
+QString ImageComposer_CutOperator::name() const
+{
+  return "cut";
+}
+
+/**
+*/
+QRectF ImageComposer_CutOperator::calcResultBoundingRect( const QRectF& theImage1Bounds, 
+                                                          const QRectF& ) const
+{
+  return theImage1Bounds;
+}
+
+/**
+*/
+void ImageComposer_CutOperator::drawResult( QPainter& thePainter,
+                                            const ImageComposer_Image& theImage1,
+                                            const ImageComposer_Image& theImage2 ) const
+{
+  theImage1.draw( thePainter );
+  theImage2.draw( thePainter );
+}
diff --git a/src/ImageComposer/ImageComposer_CutOperator.h b/src/ImageComposer/ImageComposer_CutOperator.h
new file mode 100644 (file)
index 0000000..4df8224
--- /dev/null
@@ -0,0 +1,27 @@
+
+#ifndef IMAGE_COMPOSER_CUT_OPERATOR_HEADER
+#define IMAGE_COMPOSER_CUT_OPERATOR_HEADER
+
+#include <ImageComposer_Operator.h>
+#include <QColor>
+
+/**
+  \class ImageComposer_CutOperator
+  Implementation of the cutting operator
+*/
+class IMAGE_COMPOSER_API ImageComposer_CutOperator : public ImageComposer_Operator
+{
+public:
+  ImageComposer_CutOperator( const QColor& theBackground );
+  virtual ~ImageComposer_CutOperator();
+
+  virtual QString name() const;
+
+protected:
+  virtual QRectF calcResultBoundingRect( const QRectF& theImage1Bounds, 
+                                         const QRectF& theImage2Bounds ) const;
+  virtual void drawResult( QPainter& thePainter, const ImageComposer_Image& theImage1,
+                                                 const ImageComposer_Image& theImage2 ) const;
+};
+
+#endif
diff --git a/src/ImageComposer/ImageComposer_FuseOperator.cxx b/src/ImageComposer/ImageComposer_FuseOperator.cxx
new file mode 100644 (file)
index 0000000..2c314e2
--- /dev/null
@@ -0,0 +1,46 @@
+
+#include <ImageComposer_FuseOperator.h>
+#include <ImageComposer_Image.h>
+#include <QString>
+#include <QPixmap>
+#include <QPainter>
+
+/**
+  Constructor
+  @param theBackground the background color for result image
+*/
+ImageComposer_FuseOperator::ImageComposer_FuseOperator( const QColor& theBackground )
+  : ImageComposer_Operator( theBackground )
+{
+}
+
+/**
+*/
+ImageComposer_FuseOperator::~ImageComposer_FuseOperator()
+{
+}
+
+/**
+*/
+QString ImageComposer_FuseOperator::name() const
+{
+  return "fuse";
+}
+
+/**
+*/
+QRectF ImageComposer_FuseOperator::calcResultBoundingRect( const QRectF& theImage1Bounds, 
+                                                           const QRectF& theImage2Bounds ) const
+{
+  return theImage1Bounds.united( theImage2Bounds );
+}
+
+/**
+*/
+void ImageComposer_FuseOperator::drawResult( QPainter& thePainter,
+                                             const ImageComposer_Image& theImage1,
+                                             const ImageComposer_Image& theImage2 ) const
+{
+  theImage1.draw( thePainter );
+  theImage2.draw( thePainter );
+}
diff --git a/src/ImageComposer/ImageComposer_FuseOperator.h b/src/ImageComposer/ImageComposer_FuseOperator.h
new file mode 100644 (file)
index 0000000..cffc368
--- /dev/null
@@ -0,0 +1,27 @@
+
+#ifndef IMAGE_COMPOSER_FUSE_OPERATOR_HEADER
+#define IMAGE_COMPOSER_FUSE_OPERATOR_HEADER
+
+#include <ImageComposer_Operator.h>
+#include <QColor>
+
+/**
+  \class ImageComposer_FuseOperator
+  Implementation of the fusing operator
+*/
+class IMAGE_COMPOSER_API ImageComposer_FuseOperator : public ImageComposer_Operator
+{
+public:
+  ImageComposer_FuseOperator( const QColor& theBackground );
+  virtual ~ImageComposer_FuseOperator();
+
+  virtual QString name() const;
+
+protected:
+  virtual QRectF calcResultBoundingRect( const QRectF& theImage1Bounds, 
+                                         const QRectF& theImage2Bounds ) const;
+  virtual void drawResult( QPainter& thePainter, const ImageComposer_Image& theImage1,
+                                                 const ImageComposer_Image& theImage2 ) const;
+};
+
+#endif
diff --git a/src/ImageComposer/ImageComposer_Image.cxx b/src/ImageComposer/ImageComposer_Image.cxx
new file mode 100644 (file)
index 0000000..d08eb7b
--- /dev/null
@@ -0,0 +1,171 @@
+
+#include <ImageComposer_Image.h>
+#include <ImageComposer_CropOperator.h>
+#include <ImageComposer_CutOperator.h>
+#include <ImageComposer_FuseOperator.h>
+#include <QPainter>
+
+QColor ImageComposer_Image::myDefaultBackground = TRANSPARENT;
+
+/**
+  Constructor
+*/
+ImageComposer_Image::ImageComposer_Image()
+{
+}
+
+/**
+  Destructor
+*/
+ImageComposer_Image::~ImageComposer_Image()
+{
+}
+
+/**
+  Get current image transformation
+  @return current image transformation
+*/
+QTransform ImageComposer_Image::transform() const
+{
+  return myTransform;
+}
+
+/**
+  Change current image transformation
+  @param theTransform a new image transformation
+*/
+void ImageComposer_Image::setTransform( const QTransform& theTransform )
+{
+  myTransform = theTransform;
+}
+
+/**
+  Change current image transformation
+  @param theDx the image translation along X axis of the global CS
+  @param theDy the image translation along Y axis of the global CS
+  @param theRotationDeg the image rotation in degrees around the image center
+*/
+void ImageComposer_Image::setLocalTransform( qreal theDx, qreal theDy, qreal theRotationDeg )
+{
+  QTransform aTr;
+  aTr.translate( width()*0.5, height()*0.5 );
+  aTr.rotate( theRotationDeg );
+  aTr.translate( -width()*0.5, -height()*0.5 );
+  aTr.translate( theDx, theDy );
+  myTransform = aTr;
+}
+
+/**
+  Get image's bounding rectangle in the global CS
+  @return image's bounding rectangle in the global CS
+*/
+QRectF ImageComposer_Image::boundingRect() const
+{
+  QRect aRect( 0, 0, width(), height() );
+  return myTransform.mapToPolygon( aRect ).boundingRect();
+}
+
+/**
+  Draw the image using the given painter
+  @param thePainter the painter for image drawing
+*/
+void ImageComposer_Image::draw( QPainter& thePainter ) const
+{
+  thePainter.save();
+  thePainter.setTransform( myTransform, true );
+  thePainter.drawImage( 0, 0, *this );
+  thePainter.restore();
+}
+
+/**
+  Operator of another image assignment
+  @param theImage the image to assign
+  @return the assigned image
+*/
+const ImageComposer_Image& ImageComposer_Image::operator = ( const ImageComposer_Image& theImage )
+{
+  myTransform = theImage.myTransform;
+  QImage::operator = ( ( const QImage& ) theImage );
+  return theImage;
+}
+
+/**
+  Operator of another image assignment
+  @param theImage the image to assign
+  @return the assigned image
+*/
+const QImage& ImageComposer_Image::operator = ( const QImage& theImage )
+{
+  QImage::operator = ( ( const QImage& ) theImage );
+  return theImage;
+}
+
+/**
+  Apply the given operator to the image
+  @param theOperator the operator to be applied
+  @param theImage the additional image to compose (optional)
+  @return the result image
+*/
+ImageComposer_Image ImageComposer_Image::apply( const ImageComposer_Operator& theOperator,
+                                                const ImageComposer_Image& theImage ) const
+{
+  return theOperator.process( *this, theImage );
+}
+
+/**
+  Get default background color used for image operators
+  @return default background color 
+*/
+QColor ImageComposer_Image::defaultBackground()
+{
+  return myDefaultBackground;
+}
+
+/**
+  Change default background color used for image operators
+  @param theDefaultBackground a new default background color 
+*/
+void ImageComposer_Image::setDefaultBackground( const QColor& theDefaultBackground )
+{
+  myDefaultBackground = theDefaultBackground;
+}
+
+/**
+  Operator of image cropping by a rectangle
+  @param theRect the rectangle for cropping
+  @return cropped image
+*/
+ImageComposer_Image ImageComposer_Image::operator & ( const QRect& theRect ) const
+{
+  return apply( ImageComposer_CropOperator( myDefaultBackground, theRect ) );
+}
+
+/**
+  Operator of image cropping by a path
+  @param thePath the path for cropping
+  @return cropped image
+*/
+ImageComposer_Image ImageComposer_Image::operator & ( const QPainterPath& thePath ) const
+{
+  return apply( ImageComposer_CropOperator( myDefaultBackground, thePath ) );
+}
+
+/**
+  Operator of image cutting by another image
+  @param theImage the image for cutting
+  @return cut image
+*/
+ImageComposer_Image ImageComposer_Image::operator & ( const ImageComposer_Image& theImage ) const
+{
+  return apply( ImageComposer_CutOperator( myDefaultBackground ), theImage );
+}
+
+/**
+  Operator of image fusing with another image
+  @param theImage the image for fusing
+  @return fused image
+*/
+ImageComposer_Image ImageComposer_Image::operator | ( const ImageComposer_Image& theImage ) const
+{
+  return apply( ImageComposer_FuseOperator( myDefaultBackground ), theImage );
+}
diff --git a/src/ImageComposer/ImageComposer_Image.h b/src/ImageComposer/ImageComposer_Image.h
new file mode 100644 (file)
index 0000000..8b53dca
--- /dev/null
@@ -0,0 +1,46 @@
+
+#ifndef IMAGE_COMPOSER_IMAGE_HEADER
+#define IMAGE_COMPOSER_IMAGE_HEADER
+
+#include <QImage>
+#include <ImageComposer.h>
+
+class ImageComposer_Operator;
+
+/**
+  \class ImageComposer_Image
+  Implementation of image in the global coordinate system
+*/
+class IMAGE_COMPOSER_API ImageComposer_Image : public QImage
+{
+public:
+  ImageComposer_Image();
+  ~ImageComposer_Image();
+
+  void draw( QPainter& thePainter ) const;
+
+  QTransform transform() const;
+  void setTransform( const QTransform& );
+  void setLocalTransform( qreal theDx, qreal theDy, qreal theRotationDeg );
+
+  QRectF boundingRect() const;
+
+  const ImageComposer_Image& operator = ( const ImageComposer_Image& theImage );
+  const QImage& operator = ( const QImage& theImage );
+
+  ImageComposer_Image apply( const ImageComposer_Operator& theOperator,
+                             const ImageComposer_Image& theImage = ImageComposer_Image() ) const;
+
+  static QColor defaultBackground();
+  static void setDefaultBackground( const QColor& );
+  ImageComposer_Image operator & ( const QRect& ) const;
+  ImageComposer_Image operator & ( const QPainterPath& ) const;
+  ImageComposer_Image operator & ( const ImageComposer_Image& ) const;
+  ImageComposer_Image operator | ( const ImageComposer_Image& ) const;
+
+private:
+  QTransform myTransform;            ///< the image transformation in the global CS
+  static QColor myDefaultBackground; ///< the default background color to be used in operators
+};
+
+#endif
diff --git a/src/ImageComposer/ImageComposer_Operator.cxx b/src/ImageComposer/ImageComposer_Operator.cxx
new file mode 100644 (file)
index 0000000..451629c
--- /dev/null
@@ -0,0 +1,75 @@
+
+#include <ImageComposer_Operator.h>
+#include <ImageComposer_Image.h>
+#include <QPixmap>
+#include <QPainter>
+
+/**
+  Constructor
+  @param theBackground the background color for result image
+*/
+ImageComposer_Operator::ImageComposer_Operator( const QColor& theBackground )
+: myBackground( theBackground )
+{
+}
+
+/**
+  Destructor
+*/
+ImageComposer_Operator::~ImageComposer_Operator()
+{
+}
+
+/**
+  Return name of the operator
+   @return name of the operator
+*/
+QString ImageComposer_Operator::name() const
+{
+  return "";
+}
+
+/**
+  Perform the composing of images
+  @param theImage1 the first image to compose
+  @param theImage2 the second image to compose
+  @return the result image
+*/
+ImageComposer_Image ImageComposer_Operator::process( const ImageComposer_Image& theImage1,
+                                                     const ImageComposer_Image& theImage2 ) const
+{
+  ImageComposer_Image anImage1 = theImage1;
+  ImageComposer_Image anImage2 = theImage2;
+  QTransform aInvTransform = anImage1.transform().inverted();
+  anImage1.setTransform( anImage1.transform() * aInvTransform );
+  if( !anImage2.isNull() )
+    anImage2.setTransform( anImage2.transform() * aInvTransform );
+  
+  QRectF aBounds1 = anImage1.boundingRect();
+  QRectF aBounds2;
+  if( !anImage2.isNull() )
+    aBounds2 = anImage2.boundingRect();
+  QRectF aBounds = calcResultBoundingRect( aBounds1, aBounds2 );
+
+  QTransform aTranslate;
+  aTranslate.translate( -aBounds.left(), -aBounds.top() );
+  anImage1.setTransform( anImage1.transform() * aTranslate );
+  anImage2.setTransform( anImage2.transform() * aTranslate );
+
+  QPixmap aResultImage( aBounds.width(), aBounds.height() );
+  aResultImage.fill( myBackground );
+
+  QPainter aPainter( &aResultImage );
+  aPainter.setRenderHint( QPainter::SmoothPixmapTransform, true );
+  aPainter.setRenderHint( QPainter::Antialiasing, true );
+  aPainter.setRenderHint( QPainter::HighQualityAntialiasing, true );
+
+  drawResult( aPainter, anImage1, anImage2 );
+
+  ImageComposer_Image aResult;
+  aResult = aResultImage.toImage();
+  QTransform aResultTransform = theImage1.transform();
+  aResultTransform.translate( aBounds.left(), aBounds.top() );
+  aResult.setTransform( aResultTransform );
+  return aResult;
+}
diff --git a/src/ImageComposer/ImageComposer_Operator.h b/src/ImageComposer/ImageComposer_Operator.h
new file mode 100644 (file)
index 0000000..3a21be3
--- /dev/null
@@ -0,0 +1,53 @@
+
+#ifndef IMAGE_COMPOSER_OPERATOR_HEADER
+#define IMAGE_COMPOSER_OPERATOR_HEADER
+
+#include <ImageComposer.h>
+#include <QColor>
+
+class QString;
+class QRectF;
+class QPainter;
+class QTransform;
+class ImageComposer_Image;
+
+const QColor TRANSPARENT( 255, 255, 255, 0 );
+
+/**
+  \class ImageComposer_Operator
+  Implementation of the base abstract operation for image composing
+*/
+class IMAGE_COMPOSER_API ImageComposer_Operator
+{
+public:
+  ImageComposer_Operator( const QColor& theBackground );
+  virtual ~ImageComposer_Operator();
+
+  virtual QString name() const;
+  virtual ImageComposer_Image process( const ImageComposer_Image& theImage1,
+                                       const ImageComposer_Image& theImage2 ) const;
+
+protected:
+  /**
+    Calculate bounding rectangle for the result image
+    @param theImage1Bounds bounding rectangle of the first image
+    @param theImage2Bounds bounding rectangle of the second image
+    @return calculated bounding rectangle
+  */
+  virtual QRectF calcResultBoundingRect( const QRectF& theImage1Bounds, 
+                                         const QRectF& theImage2Bounds ) const = 0;
+
+  /**
+    Draw result image using the given painter
+    @param thePainter the painter on the result image
+    @param theImage1 the first image to compose
+    @param theImage2 the second image to compose
+  */
+  virtual void drawResult( QPainter& thePainter, const ImageComposer_Image& theImage1,
+                                                 const ImageComposer_Image& theImage2 ) const = 0;
+
+private:
+  QColor myBackground;  ///< the background color for result image
+};
+
+#endif
diff --git a/src/ImageComposer/ImageComposer_Tools.cxx b/src/ImageComposer/ImageComposer_Tools.cxx
new file mode 100644 (file)
index 0000000..0a64a99
--- /dev/null
@@ -0,0 +1,3 @@
+
+#include <ImageComposer_Tools.h>
+
diff --git a/src/ImageComposer/ImageComposer_Tools.h b/src/ImageComposer/ImageComposer_Tools.h
new file mode 100644 (file)
index 0000000..a7083ab
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef IMAGE_COMPOSER_TOOLS_HEADER
+#define IMAGE_COMPOSER_TOOLS_HEADER
+
+class ImageComposer_Tools
+{
+};
+
+#endif