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] |