#include "DiffWidget.h" #include "util.h" #include <QColorDialog> #include <QLayout> #include <QMessageBox> #include <QPainter> #include <QSlider> DiffWidget::DiffWidget( char* file1, char* file2 ) { QGridLayout* l = new QGridLayout( this ); p1 = new MiniMap; p2 = new MiniMap; l->addWidget( p1, 0, 0 ); l->addWidget( p2, 1, 0 ); p1->setMinimumSize( 100, 100 ); p2->setMinimumSize( 100, 100 ); connect( p1, SIGNAL(pressed()), this, SLOT(showLeg1()) ); connect( p2, SIGNAL(pressed()), this, SLOT(showLeg2()) ); connect( p1, SIGNAL(info(QString)), this, SLOT(message(QString)) ); connect( p2, SIGNAL(info(QString)), this, SLOT(message(QString)) ); slider = new QSlider( Qt::Vertical ); QVBoxLayout* sl = new QVBoxLayout; l->addLayout( sl, 0, 1, 2, 1 ); sl->addStretch( 1 ); sl->addWidget( slider ); sl->setStretchFactor( slider, 2 ); sl->addStretch( 1 ); connect( slider, SIGNAL( valueChanged(int) ), this, SLOT( doBlend(int) ) ); blend = new ImageProjector; blend_l = new QHBoxLayout; blend_l->addWidget( blend ); l->addLayout( blend_l, 0, 2, 2, 1 ); scroll = new HandyScrollArea; blend_l->addWidget( scroll ); scroll->setBackgroundRole( QPalette::Dark ); scroll->hide(); l->setColumnStretch( 0, 1 ); l->setColumnStretch( 2, 2 ); leg1 = QImage( file1 ); leg2 = QImage( file2 ); p1->setImage( &leg1 ); p1->setInfo( imageInfo( file1, leg1.size() ) ); p2->setImage( &leg2 ); p2->setInfo( imageInfo( file2, leg2.size() ) ); if ( leg1.isNull() ) QMessageBox::critical( this, "CALAMARI error", "Unable to load " + QString(file1) ); if ( leg2.isNull() ) QMessageBox::critical( this, "CALAMARI error", "Unable to load " + QString(file2) ); if ( leg1.isNull() || leg2.isNull() ) exit( 1 ); if ( leg1.size() != leg2.size() ) { QMessageBox::warning( this, "CALAMARI warning", "The dimensions of these images are different. For diff purposes, " + QString(file1) + " has been scaled to match " + QString(file2) + "." ); leg1 = leg1.scaled( leg2.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); } diff = QImage( leg1.width(), leg1.height(), QImage::Format_ARGB32_Premultiplied ); //Scratch image scratch = QImage( leg1.width(), leg1.height(), QImage::Format_ARGB32_Premultiplied ); s_alpha = QImage( leg1.width(), leg2.height(), QImage::Format_Indexed8 ); QVector<QRgb> colors(256); for ( int i = 0 ; i < 256 ; i++ ) { colors[i] = qRgb( i, i, i ); } s_alpha.setColorTable( colors ); blend->setImage( &diff ); slider->setRange( 0, 255 ); slider->setValue( 127 ); slider->setSingleStep( 16 ); slider->setPageStep( 255 ); mask = QBitmap( leg1.size() ); imageDiff( leg1, leg2, &mask, 0.01 ); blend->setMask( &mask ); blend->setMaskColor( QColor( 100, 100, 100 ) ); } DiffWidget::~DiffWidget(void) { } void DiffWidget::chooseMaskColor() { blend->setMaskColor( QColorDialog::getColor( blend->getMaskColor(), this ) ); } void DiffWidget::doBlend( int eightBit ) { if ( diff.isNull() ) return; if ( eightBit == 0 ) { diff = leg2; } else if ( eightBit == 255 ) { diff = leg1; } else { s_alpha.fill( eightBit ); QPainter s; s.begin( &scratch ); s.drawImage( 0, 0, leg1 ); s.end(); scratch.setAlphaChannel( s_alpha ); QPainter p( &diff ); p.drawImage( 0, 0, leg2 ); p.drawImage( 0, 0, scratch ); } blend->update(); } void DiffWidget::message( QString m ) { emit showMessage( m, 0 ); } void DiffWidget::showLeg1() { slider->setValue( 255 ); } void DiffWidget::showLeg2() { slider->setValue( 0 ); } void DiffWidget::setScale( double s ) { if ( !s && scroll->isVisible() ) { scroll->takeWidget(); blend_l->addWidget( blend ); scroll->hide(); disconnect( scroll, SIGNAL( scrolledTo(double,double,double,double) ), p1, SLOT( setView(double,double,double,double) ) ); disconnect( scroll, SIGNAL( scrolledTo(double,double,double,double) ), p2, SLOT( setView(double,double,double,double) ) ); disconnect( p1, SIGNAL( mouseAt(double,double) ), scroll, SLOT( scrollTo(double,double) ) ); disconnect( p2, SIGNAL( mouseAt(double,double) ), scroll, SLOT( scrollTo(double,double) ) ); p1->setVeil( false ); p2->setVeil( false ); } else if ( s && !scroll->isVisible() ) { blend_l->removeWidget( blend ); scroll->setWidget( blend ); scroll->show(); connect( scroll, SIGNAL( scrolledTo(double,double,double,double) ), p1, SLOT( setView(double,double,double,double) ) ); connect( scroll, SIGNAL( scrolledTo(double,double,double,double) ), p2, SLOT( setView(double,double,double,double) ) ); connect( p1, SIGNAL( mouseAt(double,double) ), scroll, SLOT( scrollTo(double,double) ) ); connect( p2, SIGNAL( mouseAt(double,double) ), scroll, SLOT( scrollTo(double,double) ) ); p1->setVeil( true ); p2->setVeil( true ); } blend->setScale( s ); if ( s ) { scroll->refresh(); p1->update(); p2->update(); } } void DiffWidget::setDiffMask( bool on ) { blend->setMaskEnabled( on ); } void DiffWidget::setTolerance( int dec ) { float t = dec / 10.0; imageDiff( leg1, leg2, &mask, t ); blend->update(); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#10 | 5548 | Sam Stafford |
Only apply alpha-channel diff fix to files that actually have alpha channels. (Painting images with no alpha channels on top of each other doesn't behave like I'd hoped it would.) |
||
#9 | 5543 | Sam Stafford |
Diffing transparent images produced some weird artifacts, since blending them requires hijacking the alpha channel. Fixed it by painting the images on top of opaque backgrounds before diffing them. |
||
#8 | 5539 | Sam Stafford | Kick off another window to merge alpha channels, if present. | ||
#7 | 5516 | Sam Stafford | The M is for Merge. | ||
#6 | 5512 | Sam Stafford | UI reshuffling - pushed stencil-related options into a dialog. | ||
#5 | 5508 | Sam Stafford | Infrastructure massaging to make way for Stage Two. | ||
#4 | 5506 | Sam Stafford | Better icons and default stencil color. | ||
#3 | 5505 | Sam Stafford | Add "diff stencil". | ||
#2 | 5502 | Sam Stafford |
Status bar with handy information, and infrastructure to allow ImageProjectors to have frames. |
||
#1 | 5501 | Sam Stafford |
Codename CALAMARI. Built with Qt 4.1.3 - needs QtCore4.dll and QtGui4.dll to run. |