All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Classes | Public Types | Signals | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Properties
SciFigs::ImageLayer Class Reference

A ImageLayer is a layer to plot a scaled bitmap. More...

#include <ImageLayer.h>

Inheritance diagram for SciFigs::ImageLayer:
SciFigs::GraphContentLayer QGpGuiTools::PropertyItem QGpCoreTools::XMLClass

List of all members.

Classes

class  ReferencePoint
 Reference point to fix scale of an ImageLayer. More...

Public Types

enum  TrackingModes { Scale = 0, Histogram }

Signals

void editedColors (QRgb *colors, int numC)
void pointPicked (QPoint p)

Public Member Functions

virtual void addProperties (PropertyProxy *pp)
virtual Rect boundingRect () const
void colorHistogram (Rect r)
QString fileName () const
void grayFilter (int tol, int threshold)
virtual bool hasProperties ()
void highPassFilter (int hThres, int sThres, int vThres)
QRgb * image (int &n)
 ImageLayer (AxisWindow *parent=0)
void loadImage (QString fileName)
void loadImage ()
void lowPassFilter (int hThres, int sThres, int vThres)
virtual bool mouseReleaseEvent (QMouseEvent *e, int id=-1)
const Point2Dorigin () const
Point2Dorigin ()
virtual void properties (PropertyWidget *w) const
void redPassFilter ()
const QList< ReferencePoint > & references () const
virtual void removeProperties (PropertyProxy *pp)
const Point2Dscale () const
Point2Dscale ()
void setFileName (QString s)
void setOrigin (const Point2D &o)
virtual void setProperty (uint wid, int pid, QVariant val)
void setReferences (const QList< ReferencePoint > &ref)
void setScale (const Point2D &s)
void setScaling ()
void setXOrigin (double s)
void setXScale (double s)
void setYOrigin (double s)
void setYScale (double s)
virtual void toggleTrackingAction (bool checked, int id=-1)
virtual bool trackRectangle (int id, double rx1, double ry1, double rx2, double ry2, Qt::KeyboardModifiers m)
virtual const QString & xml_tagName () const
double xOrigin () const
double xScale () const
double yOrigin () const
double yScale () const
 ~ImageLayer ()

Static Public Member Functions

static void scaling (const QList< ReferencePoint > ref, Point2D &origin, Point2D &scale)

Static Public Attributes

static const QString xmlImageLayerTag = "ImageLayer"

Protected Member Functions

virtual void paintData (const LayerPainterRequest &lp, QPainter &p, double dotpercm) const
virtual XMLMember xml_member (XML_MEMBER_ARGS)
virtual void xml_polish (XML_POLISH_ARGS)
virtual void xml_writeChildren (XML_WRITECHILDREN_ARGS) const
virtual void xml_writeProperties (XML_WRITEPROPERTIES_ARGS) const

Properties

QString imageFile
double xOrigin
double xScale
double yOrigin
double yScale

Detailed Description

A ImageLayer is a layer to plot a scaled bitmap.


Member Enumeration Documentation

Enumerator:
Scale 
Histogram 

Constructor & Destructor Documentation

References QGpCoreTools::Point2D::setX(), QGpCoreTools::Point2D::setY(), and TRACE.

                                          :
    GraphContentLayer(parent)
{
  TRACE;
  _scale.setX(1.0); // 1 pixel/cm
  _scale.setY(-1.0); // 1 pixel/cm, reversed
}

References TRACE.

{
  TRACE;
}

Member Function Documentation

Setup property editor

Reimplemented from SciFigs::GraphContentLayer.

References SciFigs::ImageLayerProperties::addLayer(), QGpGuiTools::PropertyProxy::addReference(), QGpGuiTools::PropertyProxy::addTab(), QGpGuiTools::PropertyProxy::currentTabWidget(), QGpGuiTools::PropertyProxy::setCurrentTab(), QGpCoreTools::tr(), TRACE, and w.

{
  TRACE;
  if(pp->setCurrentTab(_tabImage)) {
    pp->addReference(this);
    ImageLayerProperties * w=static_cast<ImageLayerProperties *>(pp->currentTabWidget());
    w->addLayer(this);
  } else {
    ImageLayerProperties * w=new ImageLayerProperties;
    pp->addTab(_tabImage, tr("Image"), w, this);
    w->addLayer(this);
  }
}

Implements SciFigs::GraphContentLayer.

References TRACE, QGpCoreTools::Point2D::x(), and QGpCoreTools::Point2D::y().

Referenced by colorHistogram(), and paintData().

{
  TRACE;
  double iWidth=_trueImage.width()*_scale.x();
  double iHeight=_trueImage.height()*_scale.y();
  return Rect(_origin.x(), _origin.y(), _origin.x()+iWidth, _origin.y()+iHeight);
}

References boundingRect(), editedColors(), SciFigs::GraphContentLayer::graph(), image(), QGpCoreTools::Rect::intersect(), TRACE, w, QGpCoreTools::Point2D::x(), QGpCoreTools::Rect::x1(), QGpCoreTools::Rect::x2(), QGpCoreTools::Point2D::y(), QGpCoreTools::Rect::y1(), and QGpCoreTools::Rect::y2().

Referenced by trackRectangle().

{
  TRACE;
  if(_trueImage.isNull() || _trueImage.depth()!=32)
    return ;
  // Extract a copy of main image inside r
  Rect imageRect=r.intersect(boundingRect());
  double imageWidth=imageRect.x2() - imageRect.x1();
  double imageHeight=imageRect.y2() - imageRect.y1();
  QImage tmp=_trueImage.copy(( int) ((imageRect.x1()-_origin.x())*_scale.x()),
                                _trueImage.height()
                                - (int) ((imageRect.y2()-_origin.y())*_scale.y()),
                                (int) (imageWidth * _scale.x()),
                                (int) (imageHeight * _scale.y()) );
  int n=1 << 24;
  int * colors=new int[ n ];
  int i;
  for(i=0;i < n;i++ )
    colors[ i ]=0;
  QRgb * image=(QRgb * ) tmp.bits();
  n=tmp.numBytes() >> 2;
  int index;
  printf( "Number pixels: %i\n", n);
  printf( "Width: %i Height: %i\n", tmp.width(), tmp.height());
  for(i=0;i < n;i++, image++ ) {
    index=*image & 0x00FFFFFF;
    colors[ index ] ++;
  }
  // Count the number of non-null values
  n=1 << 24;
  int count=0;
  for(i=0;i < n;i++ ) {
    if(colors[ i ]!=0)
      count++;
  }
  printf( "Number different colors: %i\n", count);
  QRgb * diffColors=new QRgb[ count ];
  int * diffCount=new int[ count ];
  count=0;
  for(i=0;i < n;i++, image++ ) {
    if(colors[ i ]!=0) {
      diffColors[ count ]=i | 0xFF000000;
      diffCount[ count ]=colors[ i ];
      count++;
    }
  }
  delete [] colors;
  // Plot the histogram
  emit editedColors(diffColors, count);
  ColorHistogram * w =
    new ColorHistogram(diffColors, diffCount, count, graph() ->window());
  w->show();
}
void SciFigs::ImageLayer::editedColors ( QRgb *  colors,
int  numC 
) [signal]

Referenced by colorHistogram().

QString SciFigs::ImageLayer::fileName ( ) const [inline]

Referenced by properties().

{return _fileName;}
void SciFigs::ImageLayer::grayFilter ( int  tol,
int  threshold 
)

References QGpCoreTools::abs(), SciFigs::GraphContent::deepUpdate(), SciFigs::GraphContentLayer::graphContent(), image(), and TRACE.

{
  TRACE;
  if(_trueImage.isNull() || _trueImage.depth()!=32)
    return ;
  QRgb * image=(QRgb * ) _trueImage.bits();
  int n=_trueImage.numBytes() >> 2;
  for(int i=0;i < n;i++, image++ ) {
    QRgb& pix=*image;
    if(abs( qRed(pix) - qGreen(pix) ) < tol &&
         abs(qRed( pix) - qBlue(pix) ) < tol &&
         abs(qGreen( pix) - qBlue(pix) ) < tol &&
         qRed(pix) > threshold) {
      pix=0xFFFFFFFF;
    }
  }
  graphContent() ->deepUpdate();
}
virtual bool SciFigs::ImageLayer::hasProperties ( ) [inline, virtual]

Reimplemented from SciFigs::GraphContentLayer.

{return true;}
void SciFigs::ImageLayer::highPassFilter ( int  hThres,
int  sThres,
int  vThres 
)

References SciFigs::GraphContent::deepUpdate(), SciFigs::GraphContentLayer::graphContent(), image(), and TRACE.

{
  TRACE;
  if(_trueImage.isNull() || _trueImage.depth()!=32)
    return ;
  QRgb * image=(QRgb * ) _trueImage.bits();
  int n=_trueImage.numBytes() >> 2;
  int h, v, s;
  for(int i=0;i < n;i++, image++ ) {
    if( *image!=0xFFFFFFFF) {
      QColor pix( *image);
      pix.getHsv(&h, &s, &v);
      if(h <= hThres || s <= sThres || v <= vThres)
        * image=0xFFFFFFFF;
    }
  }
  graphContent() ->deepUpdate();
}
QRgb * SciFigs::ImageLayer::image ( int &  n)

References TRACE.

Referenced by colorHistogram(), grayFilter(), highPassFilter(), lowPassFilter(), and redPassFilter().

{
  TRACE;
  if(_trueImage.isNull() || _trueImage.depth()!=32)
    return 0;
  n=_trueImage.numBytes() >> 2;
  return (QRgb * ) _trueImage.bits();
}
void SciFigs::ImageLayer::loadImage ( QString  fileName)

References loadImage(), SciFigs::GraphicObject::pixelImageFilter, setFileName(), QGpCoreTools::tr(), and TRACE.

{
  TRACE;
  if(fileName.isEmpty()) {
    fileName=Message::getOpenFileName(tr( "Open an existing image" ), GraphicObject::pixelImageFilter);
    QFileInfo finfo(fileName);
    fileName=finfo.absoluteFilePath();
  }
  if(fileName.length() && QFileInfo(fileName).exists()) {
    setFileName(fileName);
    loadImage();
  }
}
void SciFigs::ImageLayer::lowPassFilter ( int  hThres,
int  sThres,
int  vThres 
)

References SciFigs::GraphContent::deepUpdate(), SciFigs::GraphContentLayer::graphContent(), image(), and TRACE.

{
  TRACE;
  if(_trueImage.isNull() || _trueImage.depth()!=32)
    return ;
  QRgb * image=(QRgb * ) _trueImage.bits();
  int n=_trueImage.numBytes() >> 2;
  int h, v, s;
  for(int i=0;i < n;i++, image++ ) {
    if( *image!=0xFFFFFFFF) {
      QColor pix( *image);
      pix.getHsv(&h, &s, &v);
      if(h >= hThres || s >= sThres || v >= vThres)
        * image=0xFFFFFFFF;
    }
  }
  graphContent() ->deepUpdate();
}
bool SciFigs::ImageLayer::mouseReleaseEvent ( QMouseEvent *  e,
int  id = -1 
) [virtual]

Reimplemented from SciFigs::GraphContentLayer.

References SciFigs::GraphContentLayer::graphContent(), pointPicked(), and TRACE.

{
  TRACE;
  switch(id) {
  case Scale:
    emit pointPicked(r2i(graphContent()->options().s2r(e->pos())));
    return true;
  default:
    return false;
  }
}
const Point2D& SciFigs::ImageLayer::origin ( ) const [inline]
{return _origin;}
{return _origin;}
void SciFigs::ImageLayer::paintData ( const LayerPainterRequest lp,
QPainter &  p,
double  dotpercm 
) const [protected, virtual]

Implements SciFigs::GraphContentLayer.

References SciFigs::GraphContentOptions::ax(), SciFigs::GraphContentOptions::ay(), boundingRect(), QGpCoreTools::Rect::intersect(), SciFigs::Scale::isEffectivelyReversed(), SciFigs::LayerPainterRequest::options(), SciFigs::GraphContentOptions::scaleX(), SciFigs::GraphContentOptions::scaleY(), SciFigs::LayerPainterRequest::terminated(), TRACE, QGpCoreTools::Point2D::x(), SciFigs::GraphContentOptions::xr2s(), SciFigs::GraphContentOptions::xVisMax(), SciFigs::GraphContentOptions::xVisMin(), QGpCoreTools::Point2D::y(), SciFigs::GraphContentOptions::yr2s(), SciFigs::GraphContentOptions::yVisMax(), and SciFigs::GraphContentOptions::yVisMin().

{
  TRACE;
  if(_trueImage.isNull())
    return ;
  const GraphContentOptions& gc=lp.options();
  Rect visRect(gc.xVisMin(), gc.yVisMin(), gc.xVisMax(), gc.yVisMax());
  visRect=visRect.intersect(boundingRect());
  if(visRect.width()>0 && visRect.height()>0) {
    if(lp.terminated()) return;
    QRect imRect(r2i(visRect.topLeft()), r2i(visRect.bottomRight()));
    QImage tmp=_trueImage.copy(imRect.normalized());
    if(lp.terminated()) return;
    QMatrix matrix;
    matrix.scale(gc.ax()*_scale.x(), gc.ay()*_scale.y());
    if(lp.terminated()) return;
    if(!tmp.isNull()) {
      int x, y;
      if(gc.scaleX().isEffectivelyReversed())
        x=gc.xr2s(visRect.x2());
      else
        x=gc.xr2s(visRect.x1());
      if(gc.scaleY().isEffectivelyReversed())
        y=gc.yr2s(visRect.y1());
      else
        y=gc.yr2s(visRect.y2());
      p.drawImage(x, y, tmp.transformed(matrix, Qt::SmoothTransformation) );
    }
  }
}
void SciFigs::ImageLayer::pointPicked ( QPoint  p) [signal]

Referenced by mouseReleaseEvent().

void SciFigs::ImageLayer::properties ( PropertyWidget w) const [virtual]

References SciFigs::GraphContent::deepUpdate(), SciFigs::GraphContentLayer::graphContent(), image(), and TRACE.

{
  TRACE;
  if(_trueImage.isNull() || _trueImage.depth()!=32)
    return ;
  QRgb * image=(QRgb * ) _trueImage.bits();
  int n=_trueImage.numBytes() >> 2;
  for(int i=0;i < n;i++, image++ ) {
    QRgb& pix=*image;
    if(qRed( pix) < qGreen(pix) ||
         qRed(pix) < qBlue(pix) )
      pix=0xFFFFFFFF;
  }
  graphContent() ->deepUpdate();
}
const QList<ReferencePoint>& SciFigs::ImageLayer::references ( ) const [inline]
{return _references;}

Clean property editor

Reimplemented from SciFigs::GraphContentLayer.

References QGpGuiTools::PropertyProxy::currentTabWidget(), SciFigs::ImageLayerProperties::removeLayer(), QGpGuiTools::PropertyProxy::removeTab(), QGpGuiTools::PropertyProxy::setCurrentTab(), TRACE, and w.

{
  TRACE;
  if(pp->setCurrentTab(_tabImage)) {
    ImageLayerProperties * w=static_cast<ImageLayerProperties *>(pp->currentTabWidget());
    w->removeLayer(this);
    pp->removeTab(_tabImage, this);
  }
}
const Point2D& SciFigs::ImageLayer::scale ( ) const [inline]
{return _scale;}
{return _scale;}
void SciFigs::ImageLayer::scaling ( const QList< ReferencePoint ref,
Point2D origin,
Point2D scale 
) [static]

References SciFigs::ImageLayer::ReferencePoint::image(), QGpCoreTools::Curve< pointType >::leastSquare(), SciFigs::ImageLayer::ReferencePoint::real(), QGpCoreTools::Point2D::setX(), QGpCoreTools::Point2D::setY(), QGpCoreTools::Point2D::x(), and QGpCoreTools::Point2D::y().

Referenced by setScaling().

{
  int n=ref.count();
  if(n>1) {
    Curve<Point2D> c(n);
    double a, b;
    for(int i=0; i<n; i++) {
      const ReferencePoint& p=ref.at(i);
      c[i]=Point2D(p.image().x(), p.real().x());
    }
    c.leastSquare(a, b);
    origin.setX(b);
    scale.setX(a);
    for(int i=0; i<n; i++) {
      const ReferencePoint& p=ref.at(i);
      c[i]=Point2D(p.image().y(), p.real().y());
    }
    c.leastSquare(a, b);
    origin.setY(b);
    scale.setY(a);
  }
}
void SciFigs::ImageLayer::setFileName ( QString  s) [inline]

Referenced by loadImage(), and setProperty().

{_fileName=s;}
void SciFigs::ImageLayer::setOrigin ( const Point2D o) [inline]
{_origin=o;}
void SciFigs::ImageLayer::setProperty ( uint  wid,
int  pid,
QVariant  val 
) [virtual]
void SciFigs::ImageLayer::setReferences ( const QList< ReferencePoint > &  ref) [inline]
{_references=ref;}
void SciFigs::ImageLayer::setScale ( const Point2D s) [inline]
{_scale=s;}

References scaling(), and TRACE.

{
  TRACE;
  scaling(_references, _origin, _scale);
}
void SciFigs::ImageLayer::setXOrigin ( double  s) [inline]
{_origin.setX(s);}
void SciFigs::ImageLayer::setXScale ( double  s) [inline]
{_scale.setX(s);}
void SciFigs::ImageLayer::setYOrigin ( double  s) [inline]
{_origin.setY(s);}
void SciFigs::ImageLayer::setYScale ( double  s) [inline]
{_scale.setY(s);}
void SciFigs::ImageLayer::toggleTrackingAction ( bool  checked,
int  id = -1 
) [virtual]

Reimplemented from SciFigs::GraphContentLayer.

References SciFigs::GraphContentLayer::beginMouseTracking(), SciFigs::GraphContentLayer::endMouseTracking(), SciFigs::GraphContentLayer::isMouseTracking(), SciFigs::LayerMouseTracking::setId(), SciFigs::LayerMouseTracking::setIdleCursor(), SciFigs::LayerMouseTracking::setRectangle(), SciFigs::LayerMouseTracking::showRectangle(), and TRACE.

Referenced by SciFigs::ImageLayerProperties::removeLayer().

{
  TRACE;
  if(id==-1) {
    QAction * a=qobject_cast<QAction *>(sender());
    if(!a) return;
    id=a->data().toInt();
  }
  if(checked) {
    if(!isMouseTracking(id)) {
      LayerMouseTracking mt(this);
      mt.setId(id);
      switch (id) {
      case Scale:
        mt.setIdleCursor(QPixmap(":/images/scalecursor.png"), 4, 4);
        break;
      case Histogram:
        mt.setIdleCursor(QPixmap(":/images/histogramcursor.png"), 4, 4);
        mt.setRectangle(true);
        mt.showRectangle();
        break;
      default:
        return; // Do not start mouse tracking
      }
      beginMouseTracking(mt);
    }
  } else {
    if(isMouseTracking(id)) {
      endMouseTracking(id);
    }
  }
}
bool SciFigs::ImageLayer::trackRectangle ( int  id,
double  rx1,
double  ry1,
double  rx2,
double  ry2,
Qt::KeyboardModifiers  m 
) [virtual]

Reimplemented from SciFigs::GraphContentLayer.

References colorHistogram(), and TRACE.

{
  TRACE;
  if(id==Histogram) {
    Rect r(rx1, ry1, rx2, ry2);
    colorHistogram(r);
  }
  return true;
}

Q PROPERTIES are part of data, unlike other types of layer

Reimplemented from SciFigs::GraphContentLayer.

References SciFigs::XMLSciFigs::data(), QGpCoreTools::XMLClass::qobject_member(), and TRACE.

{
  TRACE;
  XMLSciFigs * scifigsContext=static_cast<XMLSciFigs *>(context);
  if(scifigsContext->data()) {
    if(tag=="ReferencePoint") {
      _references.append(ReferencePoint());
      return XMLMember(&_references.last());
    } else {
      return qobject_member(this, tag, attributes, context);
    }
  }
  return XMLMember(XMLMember::Unknown);
}
virtual void SciFigs::ImageLayer::xml_polish ( XML_POLISH_ARGS  ) [inline, protected, virtual]

Reimplemented from QGpCoreTools::XMLClass.

{Q_UNUSED(context); loadImage();}
virtual const QString& SciFigs::ImageLayer::xml_tagName ( ) const [inline, virtual]

Reimplemented from SciFigs::GraphContentLayer.

{return xmlImageLayerTag;}
void SciFigs::ImageLayer::xml_writeChildren ( XML_WRITECHILDREN_ARGS  ) const [protected, virtual]

Reimplemented from QGpCoreTools::XMLClass.

References SciFigs::XMLSciFigs::data(), TRACE, and QGpCoreTools::XMLClass::xml_save().

{
  TRACE;
  XMLSciFigs * scifigsContext=static_cast<XMLSciFigs *>(context);
  if(scifigsContext->data()) {
    for(QList<ReferencePoint>::const_iterator it=_references.begin(); it!=_references.end(); it++) {
      it->xml_save(s, context);
    }
  }
}

Q PROPERTIES are part of data, unlike other types of layer

Reimplemented from SciFigs::GraphContentLayer.

References SciFigs::XMLSciFigs::data(), QGpCoreTools::XMLClass::qobject_writeProperties(), and TRACE.

{
  TRACE;
  XMLSciFigs * scifigsContext=static_cast<XMLSciFigs *>(context);
  if(scifigsContext->data()) {
    qobject_writeProperties(this, this, s, context);
  }
}
double SciFigs::ImageLayer::xOrigin ( ) const [inline]
{return _origin.x();}
double SciFigs::ImageLayer::xScale ( ) const [inline]
{return _scale.x();}
double SciFigs::ImageLayer::yOrigin ( ) const [inline]
{return _origin.y();}
double SciFigs::ImageLayer::yScale ( ) const [inline]
{return _scale.y();}

Member Data Documentation

const QString SciFigs::ImageLayer::xmlImageLayerTag = "ImageLayer" [static]

Property Documentation

QString SciFigs::ImageLayer::imageFile [read, write]
double SciFigs::ImageLayer::xOrigin [read, write]
double SciFigs::ImageLayer::xScale [read, write]
double SciFigs::ImageLayer::yOrigin [read, write]
double SciFigs::ImageLayer::yScale [read, write]

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines