A ImageLayer is a layer to plot a scaled bitmap. More...
#include <ImageLayer.h>
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 Point2D & | origin () const |
Point2D & | origin () |
virtual void | properties (PropertyWidget *w) const |
void | redPassFilter () |
const QList< ReferencePoint > & | references () const |
virtual void | removeProperties (PropertyProxy *pp) |
const Point2D & | scale () const |
Point2D & | scale () |
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 |
A ImageLayer is a layer to plot a scaled bitmap.
SciFigs::ImageLayer::ImageLayer | ( | AxisWindow * | parent = 0 | ) |
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 }
void SciFigs::ImageLayer::addProperties | ( | PropertyProxy * | pp | ) | [virtual] |
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); } }
Rect SciFigs::ImageLayer::boundingRect | ( | ) | const [virtual] |
Implements SciFigs::GraphContentLayer.
References TRACE, QGpCoreTools::Point2D::x(), and QGpCoreTools::Point2D::y().
Referenced by colorHistogram(), and paintData().
void SciFigs::ImageLayer::colorHistogram | ( | Rect | r | ) |
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.
void SciFigs::ImageLayer::loadImage | ( | ) |
References SciFigs::GraphContent::deepUpdate(), SciFigs::GraphContentLayer::graphContent(), and TRACE.
Referenced by loadImage(), and setProperty().
{ TRACE; _trueImage.load(_fileName); graphContent()->deepUpdate(); }
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;}
Point2D& SciFigs::ImageLayer::origin | ( | ) | [inline] |
{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] |
Reimplemented from SciFigs::GraphContentLayer.
References fileName(), SciFigs::ImageLayerProperties::ImageFile, QGpGuiTools::PropertyWidget::setValue(), TRACE, QGpCoreTools::Point2D::x(), SciFigs::ImageLayerProperties::XOrigin, SciFigs::ImageLayerProperties::XScale, QGpCoreTools::Point2D::y(), SciFigs::ImageLayerProperties::YOrigin, and SciFigs::ImageLayerProperties::YScale.
{ TRACE; w->setValue(ImageLayerProperties::XOrigin, _origin.x()); w->setValue(ImageLayerProperties::YOrigin, _origin.y()); w->setValue(ImageLayerProperties::XScale, _scale.x()); w->setValue(ImageLayerProperties::YScale, _scale.y()); w->setValue(ImageLayerProperties::ImageFile, fileName()); }
void SciFigs::ImageLayer::redPassFilter | ( | ) |
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;}
void SciFigs::ImageLayer::removeProperties | ( | PropertyProxy * | pp | ) | [virtual] |
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;}
Point2D& SciFigs::ImageLayer::scale | ( | ) | [inline] |
{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] |
Reimplemented from SciFigs::GraphContentLayer.
References SciFigs::GraphContent::deepUpdate(), SciFigs::GraphContentLayer::graphContent(), SciFigs::ImageLayerProperties::ImageFile, loadImage(), setFileName(), QGpCoreTools::Point2D::setX(), QGpCoreTools::Point2D::setY(), TRACE, SciFigs::ImageLayerProperties::XOrigin, SciFigs::ImageLayerProperties::XScale, SciFigs::ImageLayerProperties::YOrigin, and SciFigs::ImageLayerProperties::YScale.
{ TRACE; switch(pid) { case ImageLayerProperties::XOrigin: _origin.setX(val.toDouble()); break; case ImageLayerProperties::YOrigin: _origin.setY(val.toDouble()); break; case ImageLayerProperties::XScale: _scale.setX(val.toDouble()); break; case ImageLayerProperties::YScale: _scale.setY(val.toDouble()); break; case ImageLayerProperties::ImageFile: setFileName(val.toString()); loadImage(); break; } graphContent()->deepUpdate(); }
void SciFigs::ImageLayer::setReferences | ( | const QList< ReferencePoint > & | ref | ) | [inline] |
{_references=ref;}
void SciFigs::ImageLayer::setScale | ( | const Point2D & | s | ) | [inline] |
{_scale=s;}
void SciFigs::ImageLayer::setScaling | ( | ) |
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; }
XMLMember SciFigs::ImageLayer::xml_member | ( | XML_MEMBER_ARGS | ) | [protected, virtual] |
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); } } }
void SciFigs::ImageLayer::xml_writeProperties | ( | XML_WRITEPROPERTIES_ARGS | ) | const [protected, virtual] |
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();}
const QString SciFigs::ImageLayer::xmlImageLayerTag = "ImageLayer" [static] |
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] |