void ImageEditor::paintEvent(QPaintEvent *event) { if (!_image_loaded) return; QPainter painter(this); QPixmap pixmaptoshow; if(!_flag_mask) pixmaptoshow=QPixmap::fromImage(_image_layer.scaled(this->size(),Qt::KeepAspectRatio)); else pixmaptoshow=QPixmap::fromImage(_image_mask.scaled(this->size(),Qt::KeepAspectRatio)); painter.drawPixmap(0,0, pixmaptoshow); _real_size=pixmaptoshow.size(); //draw point if(_scissor) { QBrush blackBrush(qRgba(0, 0, 0, 255)); painter.setBrush(blackBrush); for (int i=0;i<_contourList.size();i++) for(int j=0;j<_contourList[i].size();j+=3) { QPoint ConP; ConP=QPoint(_contourList[i][j].x()*_real_size.width(),_contourList[i][j].y()*_real_size.height()); painter.drawEllipse(ConP,1,1); } for(int i=0;i<_segList.size();i+=3) { QPoint ConP; ConP=QPoint(_segList[i].x()*_real_size.width(),_segList[i].y()*_real_size.height()); painter.drawEllipse(ConP,1,1); } QBrush redBrush(qRgba(255, 0, 0, 255)); painter.setBrush(redBrush); for(int i=0;i<_fixedSeedList.size();i++) { QPoint ConP; ConP=QPoint(_fixedSeedList[i].x()*_real_size.width(),_fixedSeedList[i].y()*_real_size.height()); painter.drawEllipse(ConP,3,3); } } else { if(parameters) { for(int i=0;i<parameters->ui_points.size();i++) { if(i==parameters->ActIndex) { QBrush redBrush(qRgba(255, 0, 0, 255)); painter.setBrush(redBrush); } else { QBrush yellowBrush(qRgba(255, 255, 0, 255)); painter.setBrush(yellowBrush); } QPoint ConP; switch(_name) { case 'L': case 'l': ConP=QPoint(parameters->ui_points[i].lp.x*_real_size.width(),parameters->ui_points[i].lp.y*_real_size.height()); break; case 'R': case 'r': ConP=QPoint(parameters->ui_points[i].rp.x*_real_size.width(),parameters->ui_points[i].rp.y*_real_size.height()); } painter.drawEllipse(ConP,3,3); } } } }
// Testing get/set functions void tst_QColor::getSetCheck() { QColor obj1; // int QColor::alpha() // void QColor::setAlpha(int) obj1.setAlpha(0); QCOMPARE(obj1.alpha(), 0); obj1.setAlpha(-1); QCOMPARE(obj1.alpha(), 0); // range<0, 255> obj1.setAlpha(INT_MIN); QCOMPARE(obj1.alpha(), 0); // range<0, 255> obj1.setAlpha(255); QCOMPARE(obj1.alpha(), 255); // range<0, 255> obj1.setAlpha(INT_MAX); QCOMPARE(obj1.alpha(), 255); // range<0, 255> // qreal QColor::alphaF() // void QColor::setAlphaF(qreal) obj1.setAlphaF(0.0); QCOMPARE(obj1.alphaF(), qreal(0.0)); // range<0.0, 1.0> obj1.setAlphaF(-0.2); QCOMPARE(obj1.alphaF(), qreal(0.0)); // range<0.0, 1.0> obj1.setAlphaF(1.0); QCOMPARE(obj1.alphaF(), qreal(1.0)); // range<0.0, 1.0> obj1.setAlphaF(1.1); QCOMPARE(obj1.alphaF(), qreal(1.0)); // range<0.0, 1.0> // int QColor::red() // void QColor::setRed(int) obj1.setRed(0); QCOMPARE(obj1.red(), 0); obj1.setRed(-1); QCOMPARE(obj1.red(), 0); // range<0, 255> obj1.setRed(INT_MIN); QCOMPARE(obj1.red(), 0); // range<0, 255> obj1.setRed(255); QCOMPARE(obj1.red(), 255); // range<0, 255> obj1.setRed(INT_MAX); QCOMPARE(obj1.red(), 255); // range<0, 255> // int QColor::green() // void QColor::setGreen(int) obj1.setGreen(0); QCOMPARE(obj1.green(), 0); obj1.setGreen(-1); QCOMPARE(obj1.green(), 0); // range<0, 255> obj1.setGreen(INT_MIN); QCOMPARE(obj1.green(), 0); // range<0, 255> obj1.setGreen(255); QCOMPARE(obj1.green(), 255); // range<0, 255> obj1.setGreen(INT_MAX); QCOMPARE(obj1.green(), 255); // range<0, 255> // int QColor::blue() // void QColor::setBlue(int) obj1.setBlue(0); QCOMPARE(obj1.blue(), 0); obj1.setBlue(-1); QCOMPARE(obj1.blue(), 0); // range<0, 255> obj1.setBlue(INT_MIN); QCOMPARE(obj1.blue(), 0); // range<0, 255> obj1.setBlue(255); QCOMPARE(obj1.blue(), 255); // range<0, 255> obj1.setBlue(INT_MAX); QCOMPARE(obj1.blue(), 255); // range<0, 255> // qreal QColor::redF() // void QColor::setRedF(qreal) obj1.setRedF(0.0); QCOMPARE(obj1.redF(), qreal(0.0)); obj1.setRedF(-0.2); QCOMPARE(obj1.redF(), qreal(0.0)); // range<0.0, 1.0 obj1.setRedF(1.1); QCOMPARE(obj1.redF(), qreal(1.0)); // range<0.0, 1.0 // qreal QColor::greenF() // void QColor::setGreenF(qreal) obj1.setGreenF(0.0); QCOMPARE(obj1.greenF(), qreal(0.0)); obj1.setGreenF(-0.2); QCOMPARE(obj1.greenF(), qreal(0.0)); // range<0.0, 1.0 obj1.setGreenF(1.1); QCOMPARE(obj1.greenF(), qreal(1.0)); // range<0.0, 1.0 // qreal QColor::blueF() // void QColor::setBlueF(qreal) obj1.setBlueF(0.0); QCOMPARE(obj1.blueF(), qreal(0.0)); obj1.setBlueF(-0.2); QCOMPARE(obj1.blueF(), qreal(0.0)); // range<0.0, 1.0 obj1.setBlueF(1.1); QCOMPARE(obj1.blueF(), qreal(1.0)); // range<0.0, 1.0 // QRgb QColor::rgba() // void QColor::setRgba(QRgb) QRgb var9(qRgba(10, 20, 30, 40)); obj1.setRgba(var9); QCOMPARE(obj1.rgba(), var9); obj1.setRgba(QRgb(0)); QCOMPARE(obj1.rgba(), QRgb(0)); // QRgb QColor::rgb() // void QColor::setRgb(QRgb) QRgb var10(qRgb(10, 20, 30)); obj1.setRgb(var10); QCOMPARE(obj1.rgb(), var10); obj1.setRgb(QRgb(0)); QCOMPARE(obj1.rgb(), qRgb(0, 0, 0)); }
void ImageWriter::writeImage(QString theInputFileString, QString theOutputFileString) { //printf("Started with input : %s output: %s \n",theInputFileString,theOutputFileString); GDALAllRegister(); GDALDataset *gdalDataset = (GDALDataset *) GDALOpen( theInputFileString, GA_ReadOnly ); if ( gdalDataset == NULL ) { //valid = FALSE; return ; } int myXDimInt = gdalDataset->GetRasterXSize(); int myYDimInt = gdalDataset->GetRasterYSize(); printf("Raster is %i x %i cells\n", myXDimInt, myYDimInt); GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand( 1 ); // RasterIO() takes care of scaling down image uint *myGdalScanData = (uint*) CPLMalloc(sizeof(uint)*myXDimInt * sizeof(uint)*myYDimInt); CPLErr myResultCPLerr = myGdalBand->RasterIO(GF_Read, 0, 0, myXDimInt, myYDimInt, myGdalScanData, myXDimInt, myYDimInt, GDT_UInt32, 0, 0 ); QImage myQImage=QImage(myXDimInt,myYDimInt,32); myQImage.setAlphaBuffer(true); uint stdDevsToPlotDouble=0; bool invertHistogramFlag=false; int transparencyLevelInt=255; //calculate the adjusted matrix stats - which come into affect if the user has chosen RasterBandStats * myAdjustedRasterBandStats = new RasterBandStats(); calculateStats(myAdjustedRasterBandStats, gdalDataset); myAdjustedRasterBandStats->noDataDouble=0;//hard coding for now //to histogram stretch to a given number of std deviations //see if we are using histogram stretch using stddev and plot only within the selected number of deviations if we are //cout << "stdDevsToPlotDouble: " << cboStdDev->currentText() << " converted to " << stdDevsToPlotDouble << endl; if (stdDevsToPlotDouble > 0) { //work out how far on either side of the mean we should include data float myTotalDeviationDouble = stdDevsToPlotDouble * myAdjustedRasterBandStats->stdDevDouble; //printf("myTotalDeviationDouble: %i\n" , myTotalDeviationDouble ); //adjust min and max accordingly //only change min if it is less than mean - (n x deviations) if (myAdjustedRasterBandStats->minValDouble < (myAdjustedRasterBandStats->meanDouble-myTotalDeviationDouble)) { myAdjustedRasterBandStats->minValDouble=(myAdjustedRasterBandStats->meanDouble-myTotalDeviationDouble); //cout << "Adjusting minValDouble to: " << myAdjustedRasterBandStats->minValDouble << endl; } //only change max if it is greater than mean + (n x deviations) if (myAdjustedRasterBandStats->maxValDouble > (myAdjustedRasterBandStats->meanDouble + myTotalDeviationDouble)) { myAdjustedRasterBandStats->maxValDouble=(myAdjustedRasterBandStats->meanDouble+myTotalDeviationDouble); //cout << "Adjusting maxValDouble to: " << myAdjustedRasterBandStats->maxValDouble << endl; } //update the range myAdjustedRasterBandStats->rangeDouble = myAdjustedRasterBandStats->maxValDouble-myAdjustedRasterBandStats->minValDouble; } printf("Main ::\n"); std::cout << "Band Name : " << myAdjustedRasterBandStats->bandName << std::endl; printf("Band No : %i\n",myAdjustedRasterBandStats->bandNo); printf("Band min : %f\n",myAdjustedRasterBandStats->minValDouble); printf("Band max : %f\n",myAdjustedRasterBandStats->maxValDouble); printf("Band range: %f\n",myAdjustedRasterBandStats->rangeDouble); printf("Band mean : %f\n",myAdjustedRasterBandStats->meanDouble); printf("Band sum : %f\n",myAdjustedRasterBandStats->sumDouble); //double sumSqrDevDouble; //used to calculate stddev //double stdDevDouble; //double sumDouble; //int elementCountInt; //double noDataDouble; //set up the three class breaks for pseudocolour mapping double myBreakSizeDouble = myAdjustedRasterBandStats->rangeDouble / 3; double myClassBreakMin1 = myAdjustedRasterBandStats->minValDouble; double myClassBreakMax1 = myAdjustedRasterBandStats->minValDouble + myBreakSizeDouble; double myClassBreakMin2 = myClassBreakMax1; double myClassBreakMax2 = myClassBreakMin2 + myBreakSizeDouble; double myClassBreakMin3 = myClassBreakMax2; double myClassBreakMax3 = myAdjustedRasterBandStats->maxValDouble; printf ("ClassBreak size : %f \n",myBreakSizeDouble); printf ("ClassBreak 1 : %f - %f\n",myClassBreakMin1,myClassBreakMax1); printf ("ClassBreak 2 : %f - %f\n",myClassBreakMin2,myClassBreakMax2); printf ("ClassBreak 3 : %f - %f\n",myClassBreakMin3,myClassBreakMax3); int myRedInt=0; int myGreenInt=0; int myBlueInt=0; for (int myColumnInt = 0; myColumnInt < myYDimInt; myColumnInt++) { for (int myRowInt =0; myRowInt < myXDimInt; myRowInt++) { int myInt=myGdalScanData[myColumnInt*myXDimInt + myRowInt]; //dont draw this point if it is no data ! //double check that myInt >= min and <= max //this is relevant if we are plotting within stddevs if ((myInt < myAdjustedRasterBandStats->minValDouble ) && (myInt != myAdjustedRasterBandStats->noDataDouble)) { myInt = static_cast<int>(myAdjustedRasterBandStats->minValDouble); } if ((myInt > myAdjustedRasterBandStats->maxValDouble) && (myInt != myAdjustedRasterBandStats->noDataDouble)) { myInt = static_cast<int>(myAdjustedRasterBandStats->maxValDouble); } if (myInt==myAdjustedRasterBandStats->noDataDouble) { //hardcoding to white for now myRedInt = 255; myBlueInt = 255; myGreenInt =255; } else if(!invertHistogramFlag) { //check if we are in the first class break if ((myInt >= myClassBreakMin1) && (myInt < myClassBreakMax1) ) { myRedInt = 0; myBlueInt = 255; myGreenInt = static_cast<int>(((255/myAdjustedRasterBandStats->rangeDouble) * (myInt-myClassBreakMin1))*3); } //check if we are in the second class break else if ((myInt >= myClassBreakMin2) && (myInt < myClassBreakMax2) ) { myRedInt = static_cast<int>(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin2)/1))*3); myBlueInt = static_cast<int>(255-(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin2)/1))*3)); myGreenInt = 255; } //otherwise we must be in the third classbreak else { myRedInt = 255; myBlueInt = 0; myGreenInt = static_cast<int>(255-(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin3)/1)*3))); } } else //invert histogram toggle is on { //check if we are in the first class break if ((myInt >= myClassBreakMin1) && (myInt < myClassBreakMax1) ) { myRedInt = 255; myBlueInt = 0; myGreenInt = static_cast<int>(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin1)/1)*3)); } //check if we are in the second class break else if ((myInt >= myClassBreakMin2) && (myInt < myClassBreakMax2) ) { myRedInt = static_cast<int>(255-(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin2)/1))*3)); myBlueInt = static_cast<int>(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin2)/1))*3); myGreenInt = 255; } //otherwise we must be in the third classbreak else { myRedInt = 0; myBlueInt = 255; myGreenInt = static_cast<int>(255-(((255/myAdjustedRasterBandStats->rangeDouble) * (myInt-myClassBreakMin3))*3)); } } myQImage.setPixel( myRowInt, myColumnInt, qRgba( myRedInt, myGreenInt, myBlueInt, transparencyLevelInt )); } } //draw with the experimental transaparency support CPLFree(myGdalScanData); GDALClose(gdalDataset); printf("Saving image...\n"); myQImage.save(theOutputFileString,"PNG"); return ; }
double QgsComposerHtml::findNearbyPageBreak( double yPos ) { if ( !mWebPage || !mRenderedPage || !mUseSmartBreaks ) { return yPos; } //convert yPos to pixels int idealPos = yPos * htmlUnitsToMM(); //if ideal break pos is past end of page, there's nothing we need to do if ( idealPos >= mRenderedPage->height() ) { return yPos; } int maxSearchDistance = mMaxBreakDistance * htmlUnitsToMM(); //loop through all lines just before ideal break location, up to max distance //of maxSearchDistance int changes = 0; QRgb currentColor; bool currentPixelTransparent = false; bool previousPixelTransparent = false; QRgb pixelColor; QList< QPair<int, int> > candidates; int minRow = qMax( idealPos - maxSearchDistance, 0 ); for ( int candidateRow = idealPos; candidateRow >= minRow; --candidateRow ) { changes = 0; currentColor = qRgba( 0, 0, 0, 0 ); //check all pixels in this line for ( int col = 0; col < mRenderedPage->width(); ++col ) { //count how many times the pixels change color in this row //eventually, we select a row to break at with the minimum number of color changes //since this is likely a line break, or gap between table cells, etc //but very unlikely to be midway through a text line or picture pixelColor = mRenderedPage->pixel( col, candidateRow ); currentPixelTransparent = qAlpha( pixelColor ) == 0; if ( pixelColor != currentColor && !( currentPixelTransparent && previousPixelTransparent ) ) { //color has changed currentColor = pixelColor; changes++; } previousPixelTransparent = currentPixelTransparent; } candidates.append( qMakePair( candidateRow, changes ) ); } //sort candidate rows by number of changes ascending, row number descending qSort( candidates.begin(), candidates.end(), candidateSort ); //first candidate is now the largest row with smallest number of changes //ok, now take the mid point of the best candidate position //we do this so that the spacing between text lines is likely to be split in half //otherwise the html will be broken immediately above a line of text, which //looks a little messy int maxCandidateRow = candidates[0].first; int minCandidateRow = maxCandidateRow + 1; int minCandidateChanges = candidates[0].second; QList< QPair<int, int> >::iterator it; for ( it = candidates.begin(); it != candidates.end(); ++it ) { if (( *it ).second != minCandidateChanges || ( *it ).first != minCandidateRow - 1 ) { //no longer in a consecutive block of rows of minimum pixel color changes //so return the row mid-way through the block //first converting back to mm return ( minCandidateRow + ( maxCandidateRow - minCandidateRow ) / 2 ) / htmlUnitsToMM(); } minCandidateRow = ( *it ).first; } //above loop didn't work for some reason //return first candidate converted to mm return candidates[0].first / htmlUnitsToMM(); }
* the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "qgsrasterrenderer.h" #include "qgsrastertransparency.h" #include <QCoreApplication> #include <QDomDocument> #include <QDomElement> #include <QImage> #include <QPainter> // See #9101 before any change of NODATA_COLOR! const QRgb QgsRasterRenderer::NODATA_COLOR = qRgba( 0, 0, 0, 0 ); QgsRasterRenderer::QgsRasterRenderer( QgsRasterInterface* input, const QString& type ) : QgsRasterInterface( input ) , mType( type ), mOpacity( 1.0 ), mRasterTransparency( nullptr ) , mAlphaBand( -1 ) //, mInvertColor( false ) { } QgsRasterRenderer::~QgsRasterRenderer() { delete mRasterTransparency; } int QgsRasterRenderer::bandCount() const {
void QAnimationWriter::appendFrame(const QImage& frm, const QPoint& offset) { if (!dev) return; const QImage frame = frm.convertToFormat(QImage::Format_RGB32); const int alignx = 1; if (prev.isNull() || !d->canCompose()) { d->setImage(frame); } else { bool done; int minx, maxx, miny, maxy; int w = frame.width(); int h = frame.height(); const quint32 *framePtr = reinterpret_cast<const quint32*>(frame.bits()); const quint32 *prevPtr = reinterpret_cast<const quint32*>(prev.bits()); const int frameStride = frame.bytesPerLine() / sizeof(quint32); const int prevStride = prev.bytesPerLine() / sizeof(quint32); // Find left edge of change done = false; for (minx = 0; minx < w && !done; ++minx) { const quint32 *p1 = framePtr + minx; const quint32 *p2 = prevPtr + minx + offset.x(); for (int y = 0; y < h; ++y) { if (*p1 != *p2) { done = true; break; } p1 += frameStride; p2 += prevStride; } } --minx; // Find right edge of change done = false; for (maxx = w-1; maxx >= 0 && !done; --maxx) { const quint32 *p1 = framePtr + maxx; const quint32 *p2 = prevPtr + maxx + offset.x(); for (int y = 0; y < h; ++y) { if (*p1 != *p2) { done = true; break; } p1 += frameStride; p2 += prevStride; } } ++maxx; // Find top edge of change done = false; for (miny = 0; miny < h && !done; ++miny) { const quint32 *p1 = framePtr + miny * frameStride; const quint32 *p2 = prevPtr + miny * prevStride + offset.x(); for (int x = 0; x < w; ++x) { if (*p1 != *p2) { done = true; break; } ++p1; ++p2; } } --miny; // Find right edge of change done = false; for (maxy = h-1; maxy >= 0 && !done; --maxy) { const quint32 *p1 = framePtr + maxy * frameStride; const quint32 *p2 = prevPtr + maxy * prevStride + offset.x(); for (int x = 0; x < w; ++x) { if (*p1 != *p2) { done = true; break; } ++p1; ++p2; } } ++maxy; if (minx > maxx) minx = maxx = 0; if (miny > maxy) miny = maxy = 0; if (alignx > 1) { minx -= minx % alignx; maxx = maxx - maxx % alignx + alignx - 1; } int dw = maxx - minx + 1; int dh = maxy - miny + 1; QImage diff(dw, dh, QImage::Format_ARGB32); int x, y; for (y = 0; y < dh; ++y) { QRgb* li = (QRgb*)frame.scanLine(y+miny)+minx; QRgb* lp = (QRgb*)prev.scanLine(y+miny+offset.y())+minx+offset.x(); QRgb* ld = (QRgb*)diff.scanLine(y); if (alignx) { for (x = 0; x < dw; x += alignx) { int i; for (i = 0; i < alignx; ++i) { if (li[x+i] != lp[x+i]) break; } if (i == alignx) { // All the same for (i = 0; i < alignx; ++i) ld[x+i] = qRgba(0,0,0,0); } else { // Some different for (i = 0; i < alignx; ++i) ld[x+i] = 0xff000000 | li[x+i]; } } } else { for (x = 0; x < dw; ++x) { if (li[x] != lp[x]) ld[x] = 0xff000000 | li[x]; else ld[x] = qRgba(0,0,0,0); } } } d->composeImage(diff, QPoint(minx, miny) + offset); } if (prev.isNull() || (prev.size() == frame.size() && offset == QPoint(0,0))) { prev = frame; } else { QPainter p(&prev); p.drawImage(offset.x(), offset.y(), frame, 0, 0, frame.width(), frame.height()); } }
#include "ColorTabBar.h" #include <QPainter> #include <QtEvents> static const QRgb g_TabDefaultColor[5] = { qRgba(237, 28, 36, 200), qRgba(255, 127, 39, 200), qRgba(34, 177, 36, 200), qRgba(0, 162, 232, 200), qRgba(63, 72, 204, 200) }; QColorTabBar::QColorTabBar(QWidget *parent) : QTabBar(parent) { m_bNotify = false; m_nNotifyIndex = -1; m_nActiveIndex = -1; m_nHoverIndex = -1; m_nBlinkCount = 0; m_bHorz = true; m_nBlinkIndex = -1; m_bBlinkFalg = false; m_nTimerBlink = 0; setMouseTracking( true );
QgsRasterBlock *QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle const &extent, int width, int height, QgsRasterBlockFeedback *feedback ) { std::unique_ptr< QgsRasterBlock > outputBlock( new QgsRasterBlock() ); if ( !mInput || mClassData.isEmpty() ) { return outputBlock.release(); } std::shared_ptr< QgsRasterBlock > inputBlock( mInput->block( bandNo, extent, width, height, feedback ) ); if ( !inputBlock || inputBlock->isEmpty() ) { QgsDebugMsg( QStringLiteral( "No raster data!" ) ); return outputBlock.release(); } double currentOpacity = mOpacity; //rendering is faster without considering user-defined transparency bool hasTransparency = usesTransparency(); std::shared_ptr< QgsRasterBlock > alphaBlock; if ( mAlphaBand > 0 && mAlphaBand != mBand ) { alphaBlock.reset( mInput->block( mAlphaBand, extent, width, height, feedback ) ); if ( !alphaBlock || alphaBlock->isEmpty() ) { return outputBlock.release(); } } else if ( mAlphaBand == mBand ) { alphaBlock = inputBlock; } if ( !outputBlock->reset( Qgis::ARGB32_Premultiplied, width, height ) ) { return outputBlock.release(); } QRgb myDefaultColor = NODATA_COLOR; //use direct data access instead of QgsRasterBlock::setValue //because of performance unsigned int *outputData = ( unsigned int * )( outputBlock->bits() ); qgssize rasterSize = ( qgssize )width * height; bool isNoData = false; for ( qgssize i = 0; i < rasterSize; ++i ) { const double value = inputBlock->valueAndNoData( i, isNoData ); if ( isNoData ) { outputData[i] = myDefaultColor; continue; } int val = static_cast< int >( value ); if ( !mColors.contains( val ) ) { outputData[i] = myDefaultColor; continue; } if ( !hasTransparency ) { outputData[i] = mColors.value( val ); } else { currentOpacity = mOpacity; if ( mRasterTransparency ) { currentOpacity = mRasterTransparency->alphaValue( val, mOpacity * 255 ) / 255.0; } if ( mAlphaBand > 0 ) { currentOpacity *= alphaBlock->value( i ) / 255.0; } QRgb c = mColors.value( val ); outputData[i] = qRgba( currentOpacity * qRed( c ), currentOpacity * qGreen( c ), currentOpacity * qBlue( c ), currentOpacity * qAlpha( c ) ); } } return outputBlock.release(); }
void knob::drawKnob( QPainter * _p ) { if( updateAngle() == false && !m_cache.isNull() ) { _p->drawImage( 0, 0, m_cache ); return; } m_cache = QImage( size(), QImage::Format_ARGB32 ); m_cache.fill( qRgba( 0, 0, 0, 0 ) ); QPainter p( &m_cache ); QPoint mid; if( m_knobNum == knobStyled ) { p.setRenderHint( QPainter::Antialiasing ); // Perhaps this can move to setOuterRadius() if( m_outerColor ) { QRadialGradient gradient( centerPoint(), outerRadius() ); gradient.setColorAt(0.4, _p->pen().brush().color() ); gradient.setColorAt(1, *m_outerColor ); p.setPen( QPen( gradient, lineWidth(), Qt::SolidLine, Qt::RoundCap ) ); } else { QPen pen = p.pen(); pen.setWidth( (int) lineWidth() ); pen.setCapStyle( Qt::RoundCap ); p.setPen( pen ); } p.drawLine( calculateLine( centerPoint(), outerRadius(), innerRadius() ) ); p.end(); _p->drawImage( 0, 0, m_cache ); return; } // Old-skool knobs const float radius = m_knobPixmap->width() / 2.0f - 1; mid = QPoint( width() / 2, m_knobPixmap->height() / 2 ); p.drawPixmap( static_cast<int>( width() / 2 - m_knobPixmap->width() / 2 ), 0, *m_knobPixmap ); p.setRenderHint( QPainter::Antialiasing ); const int centerAngle = angleFromValue( model()->centerValue(), model()->minValue(), model()->maxValue(), m_totalAngle ); const int arcLineWidth = 2; const int arcRectSize = m_knobPixmap->width() - arcLineWidth; QColor col; if( m_knobNum == knobVintage_32 ) { col = QApplication::palette().color( QPalette::Active, QPalette::Shadow ); } else { col = QApplication::palette().color( QPalette::Active, QPalette::WindowText ); } col.setAlpha( 70 ); p.setPen( QPen( col, 2 ) ); p.drawArc( mid.x() - arcRectSize/2, 1, arcRectSize, arcRectSize, 315*16, 16*m_totalAngle ); switch( m_knobNum ) { case knobSmall_17: { p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::WindowText ), 2 ) ); p.drawLine( calculateLine( mid, radius-2 ) ); break; } case knobBright_26: { p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::WindowText ), 2 ) ); p.drawLine( calculateLine( mid, radius-5 ) ); break; } case knobDark_28: { p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::WindowText ), 2 ) ); const float rb = qMax<float>( ( radius - 10 ) / 3.0, 0.0 ); const float re = qMax<float>( ( radius - 4 ), 0.0 ); QLineF ln = calculateLine( mid, re, rb ); ln.translate( 1, 1 ); p.drawLine( ln ); break; } case knobGreen_17: { p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::BrightText), 2 ) ); p.drawLine( calculateLine( mid, radius ) ); break; } case knobVintage_32: { p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::Shadow), 2 ) ); p.drawLine( calculateLine( mid, radius-2, 2 ) ); break; } } p.drawArc( mid.x() - arcRectSize/2, 1, arcRectSize, arcRectSize, (90-centerAngle)*16, -16*(m_angle-centerAngle) ); p.end(); _p->drawImage( 0, 0, m_cache ); }
QImage SpecularmapGenerator::calculateSpecmap(QImage input, double scale, double contrast) { QImage result(input.width(), input.height(), QImage::Format_ARGB32); //generate contrast lookup table unsigned short contrastLookup[256]; double newValue = 0; for(int i = 0; i < 256; i++) { newValue = (double)i; newValue /= 255.0; newValue -= 0.5; newValue *= contrast; newValue += 0.5; newValue *= 255; if(newValue < 0) newValue = 0; if(newValue > 255) newValue = 255; contrastLookup[i] = (unsigned short)newValue; } #pragma omp parallel for // OpenMP //for every row of the image for(int y = 0; y < result.height(); y++) { QRgb *scanline = (QRgb*) result.scanLine(y); //for every column of the image for(int x = 0; x < result.width(); x++) { double r, g, b, a; double intensity = 0.0; QColor pxColor = QColor(input.pixel(x, y)); r = pxColor.redF() * redMultiplier; g = pxColor.greenF() * greenMultiplier; b = pxColor.blueF() * blueMultiplier; a = pxColor.alphaF() * alphaMultiplier; if(mode == IntensityMap::AVERAGE) { //take the average out of all selected channels double multiplierSum = (redMultiplier + greenMultiplier + blueMultiplier + alphaMultiplier); if(multiplierSum == 0.0) multiplierSum = 1.0; intensity = (r + g + b + a) / multiplierSum; } else if(mode == IntensityMap::MAX) { //take the maximum out of all selected channels double tempMaxRG = std::max(r, g); double tempMaxBA = std::max(b, a); intensity = std::max(tempMaxRG, tempMaxBA); } //apply scale (brightness) intensity *= scale; if(intensity > 1.0) intensity = 1.0; //convert intensity to the 0-255 range int c = (int)(255.0 * intensity); //apply contrast c = (int)contrastLookup[c]; //write color into image pixel scanline[x] = qRgba(c, c, c, pxColor.alpha()); } } return result; }
void MainWindow::onNewSketch() { for (int i = 0; i < parametriclsystem::NUM_LAYERS; ++i) { glWidget->sketch[i].fill(qRgba(255, 255, 255, 0)); } glWidget->update(); }
void TrackerArenaForm::overlapOpenGL(QPainter& painter) { if (model_->readyFrameInd_ < 0) return; // draw track adornments const float r = 5; std::vector<TrackUIItem*> trackList; model_->getTrackList(trackList); for (auto pTrack : trackList) { BlobRegistrationRecord blobInfo = pTrack->LastPosition; auto pos = blobInfo.ObsPosPixExactOrApprox; if (!pTrack->IsLive) { painter.setPen(QColor::fromRgb(0, 0, 0)); painter.drawEllipse(pos.x - r, pos.y - r, 2 * r, 2 * r); } else { painter.setPen(QColor::fromRgb(0, 0, 0)); painter.drawText(pos.x, pos.y, QString::number(pTrack->TrackId)); QColor penColor; if (blobInfo.HasObservation) penColor = QColor::fromRgba(qRgba(0, 255, 0, 255)); else penColor = QColor::fromRgb(qRgba(0, 0, 255, 255)); painter.setPen(penColor); painter.drawEllipse(pos.x - r, pos.y - r, 2 * r, 2 * r); } // attempt to estimate most probable hypothesis for current track //int latestFrameInd = pTrack->latesetFrameIndExcl(); //TrackChangePerFrame change; //if (model_->getLatestTrack(latestFrameInd, pTrack->TrackId, change)) //{ // auto pos = change.ObservationPosPixExactOrApprox; // painter.setPen(QColor::fromRgb(0, 0, 0)); // painter.drawText(pos.x, pos.y, QString::number(pTrack->TrackId)); // QColor penColor; // if (change.UpdateType == TrackChangeUpdateType::ObservationUpdate || change.UpdateType == TrackChangeUpdateType::New) // penColor = QColor::fromRgb(0, 255, 0); // else if (change.UpdateType == TrackChangeUpdateType::NoObservation) // penColor = QColor::fromRgb(255, 255, 0); // else if (change.UpdateType == TrackChangeUpdateType::Pruned) // penColor = QColor::fromRgb(255, 0, 0); // painter.setPen(penColor); // // painter.drawEllipse(pos.x - r, pos.y - r, 2 * r, 2 * r); //} //else //{ // qDebug() << "Can't get latest track hypothesis TrackId=" << pTrack->TrackId; // CV_Assert(false); //} } }
inline QRgb grayRgb(QRgb rgb) { int gray = (qRed(rgb) + qGreen(rgb) + qBlue(rgb)) / 3; return qRgba(gray, gray, gray, qAlpha(rgb) / 2); }
void * QgsMultiBandColorRenderer::readBlock( int bandNo, QgsRectangle const & extent, int width, int height ) { Q_UNUSED( bandNo ); if ( !mInput ) { return 0; } //In some (common) cases, we can simplify the drawing loop considerably and save render time bool fastDraw = ( !usesTransparency() && mRedBand > 0 && mGreenBand > 0 && mBlueBand > 0 && mAlphaBand < 1 && !mRedContrastEnhancement && !mGreenContrastEnhancement && !mBlueContrastEnhancement && !mInvertColor ); QgsRasterInterface::DataType redType = QgsRasterInterface::UnknownDataType; if ( mRedBand > 0 ) { redType = ( QgsRasterInterface::DataType )mInput->dataType( mRedBand ); } QgsRasterInterface::DataType greenType = QgsRasterInterface::UnknownDataType; if ( mGreenBand > 0 ) { greenType = ( QgsRasterInterface::DataType )mInput->dataType( mGreenBand ); } QgsRasterInterface::DataType blueType = QgsRasterInterface::UnknownDataType; if ( mBlueBand > 0 ) { blueType = ( QgsRasterInterface::DataType )mInput->dataType( mBlueBand ); } QgsRasterInterface::DataType transparencyType = QgsRasterInterface::UnknownDataType; if ( mAlphaBand > 0 ) { transparencyType = ( QgsRasterInterface::DataType )mInput->dataType( mAlphaBand ); } QSet<int> bands; if ( mRedBand > 0 ) { bands << mRedBand; } if ( mGreenBand > 0 ) { bands << mGreenBand; } if ( mBlueBand > 0 ) { bands << mBlueBand; } if ( bands.size() < 1 ) { return 0; //no need to draw anything if no band is set } if ( mAlphaBand > 0 ) { bands << mAlphaBand; } QMap<int, void*> bandData; void* defaultPointer = 0; QSet<int>::const_iterator bandIt = bands.constBegin(); for ( ; bandIt != bands.constEnd(); ++bandIt ) { bandData.insert( *bandIt, defaultPointer ); } void* redData = 0; void* greenData = 0; void* blueData = 0; void* alphaData = 0; bandIt = bands.constBegin(); for ( ; bandIt != bands.constEnd(); ++bandIt ) { bandData[*bandIt] = mInput->block( *bandIt, extent, width, height ); if ( !bandData[*bandIt] ) { // We should free the alloced mem from block(). QgsDebugMsg( "No input band" ); bandIt--; for ( ; bandIt != bands.constBegin(); bandIt-- ) { VSIFree( bandData[*bandIt] ); } return 0; } } if ( mRedBand > 0 ) { redData = bandData[mRedBand]; } if ( mGreenBand > 0 ) { greenData = bandData[mGreenBand]; } if ( mBlueBand > 0 ) { blueData = bandData[mBlueBand]; } if ( mAlphaBand > 0 ) { alphaData = bandData[mAlphaBand]; } QImage img( width, height, QImage::Format_ARGB32_Premultiplied ); if ( img.isNull() ) { QgsDebugMsg( "Could not create QImage" ); bandIt = bands.constBegin(); for ( ; bandIt != bands.constEnd(); ++bandIt ) { VSIFree( bandData[*bandIt] ); } return 0; } QRgb* imageScanLine = 0; int currentRasterPos = 0; int redVal = 0; int greenVal = 0; int blueVal = 0; QRgb defaultColor = qRgba( 255, 255, 255, 0 ); double currentOpacity = mOpacity; //opacity (between 0 and 1) for ( int i = 0; i < height; ++i ) { imageScanLine = ( QRgb* )( img.scanLine( i ) ); for ( int j = 0; j < width; ++j ) { if ( fastDraw ) //fast rendering if no transparency, stretching, color inversion, etc. { redVal = readValue( redData, redType, currentRasterPos ); greenVal = readValue( greenData, greenType, currentRasterPos ); blueVal = readValue( blueData, blueType, currentRasterPos ); if ( mInput->isNoDataValue( mRedBand, redVal ) || mInput->isNoDataValue( mGreenBand, greenVal ) || mInput->isNoDataValue( mBlueBand, blueVal ) ) { imageScanLine[j] = defaultColor; } else { imageScanLine[j] = qRgba( redVal, greenVal, blueVal, 255 ); } ++currentRasterPos; continue; } bool isNoData = false; if ( mRedBand > 0 ) { redVal = readValue( redData, redType, currentRasterPos ); if ( mInput->isNoDataValue( mRedBand, redVal ) ) isNoData = true; } if ( mGreenBand > 0 ) { greenVal = readValue( greenData, greenType, currentRasterPos ); if ( mInput->isNoDataValue( mGreenBand, greenVal ) ) isNoData = true; } if ( mBlueBand > 0 ) { blueVal = readValue( blueData, blueType, currentRasterPos ); if ( mInput->isNoDataValue( mBlueBand, blueVal ) ) isNoData = true; } if ( isNoData ) { imageScanLine[j] = defaultColor; ++currentRasterPos; continue; } //apply default color if red, green or blue not in displayable range if (( mRedContrastEnhancement && !mRedContrastEnhancement->isValueInDisplayableRange( redVal ) ) || ( mGreenContrastEnhancement && !mGreenContrastEnhancement->isValueInDisplayableRange( redVal ) ) || ( mBlueContrastEnhancement && !mBlueContrastEnhancement->isValueInDisplayableRange( redVal ) ) ) { imageScanLine[j] = defaultColor; ++currentRasterPos; continue; } //stretch color values if ( mRedContrastEnhancement ) { redVal = mRedContrastEnhancement->enhanceContrast( redVal ); } if ( mGreenContrastEnhancement ) { greenVal = mGreenContrastEnhancement->enhanceContrast( greenVal ); } if ( mBlueContrastEnhancement ) { blueVal = mBlueContrastEnhancement->enhanceContrast( blueVal ); } if ( mInvertColor ) { redVal = 255 - redVal; greenVal = 255 - greenVal; blueVal = 255 - blueVal; } //opacity currentOpacity = mOpacity; if ( mRasterTransparency ) { currentOpacity = mRasterTransparency->alphaValue( redVal, greenVal, blueVal, mOpacity * 255 ) / 255.0; } if ( mAlphaBand > 0 ) { currentOpacity *= ( readValue( alphaData, transparencyType, currentRasterPos ) / 255.0 ); } if ( doubleNear( currentOpacity, 1.0 ) ) { imageScanLine[j] = qRgba( redVal, greenVal, blueVal, 255 ); } else { imageScanLine[j] = qRgba( currentOpacity * redVal, currentOpacity * greenVal, currentOpacity * blueVal, currentOpacity * 255 ); } ++currentRasterPos; } } bandIt = bands.constBegin(); for ( ; bandIt != bands.constEnd(); ++bandIt ) { VSIFree( bandData[*bandIt] ); } void * data = VSIMalloc( img.byteCount() ); if ( ! data ) { QgsDebugMsg( QString( "Couldn't allocate output data memory of % bytes" ).arg( img.byteCount() ) ); return 0; } return memcpy( data, img.bits(), img.byteCount() ); }
void BitmapImage::add(BitmapImage* bitmapImage) { QImage* image2 = bitmapImage->image; QRect newBoundaries; if ( image->width() == 0 || image->height() == 0 ) { newBoundaries = bitmapImage->boundaries; } else { newBoundaries = boundaries.united( bitmapImage->boundaries ); } extend( newBoundaries ); QPoint offset = bitmapImage->boundaries.topLeft() - boundaries.topLeft(); for(int y=0; y<image2->height(); y++) { for(int x=0; x<image2->width(); x++) { /*QRgb p2 = image2->pixel(x,y); int r2 = qRed(p2); int g2 = qGreen(p2); int b2 = qBlue(p2); int a2 = qAlpha(p2); int r, g, b, a; r=0; g=0; b=0; a=0; for(int u=0; u<1; u++) { for(int v=0; v<1;v++) { if (boundaries.contains( bitmapImage->boundaries.topLeft() + QPoint(x+u,y+v) )) { QRgb p1 = image->pixel(offset.x()+x+u,offset.y()+y+v); int r1 = qRed(p1); int g1 = qGreen(p1); int b1 = qBlue(p1); int a1 = qAlpha(p1); r = r + r1; g = g + g1; b = b + b1; a = a + a1; } } } r = r/1; g = g/1; b = b/1; a = a/1; //r = 255; //g = 0; //b = 0; a = 255; QRgb p1 = image->pixel(offset.x()+x,offset.y()+y); int r1 = qRed(p1); int g1 = qGreen(p1); int b1 = qBlue(p1); int a1 = qAlpha(p1); r = (r1*(255-r2) + r2*r)/255; g = (g1*(255-g2) + g2*g)/255; b = (b1*(255-b2) + b2*b)/255; a = (a1*(255-a2) + a2*a)/255;*/ QRgb p1 = image->pixel(offset.x()+x,offset.y()+y); QRgb p2 = image2->pixel(x,y); int a1 = qAlpha(p1); int a2 = qAlpha(p2); int r1 = qRed(p1); int r2 = qRed(p2); // remember that the bitmap format is RGB32 Premultiplied int g1 = qGreen(p1); int g2 = qGreen(p2); int b1 = qBlue(p1); int b2 = qBlue(p2); /*qreal a1 = qAlpha(p1); qreal a2 = qAlpha(p2); qreal r1 = qRed(p1); qreal r2 = qRed(p2); // remember that the bitmap format is RGB32 Premultiplied qreal g1 = qGreen(p1); qreal g2 = qGreen(p2); qreal b1 = qBlue(p1); qreal b2 = qBlue(p2);*/ // unite int a = qMax(a1, a2); int r = qMax(r1, r2); int g = qMax(g1, g2); int b = qMax(b1, b2); // blend /*int a = a2 + a1*(255-a2)/255; int r = r2 + r1*(255-a2)/255; int g = g2 + g1*(255-a2)/255; int b = b2 + b1*(255-a2)/255;*/ // source /*int a = a2; int r = r2; int g = g2; int b = b2;*/ /*int a = qRound(a1+a2); int r = qRound((a1+a2)*((r1+0.)/a1+(r2+0.)/a2)/1); int g = qRound((a1+a2)*((g1+0.)/a1+(g2+0.)/a2)/1); int b = qRound((a1+a2)*((b1+0.)/a1+(b2+0.)/a2)/1);*/ // add /*int a = qMin(255, qRound(1.0*(a1+a2))); int r = qMin(255, qRound(0.5*(r1+r2))); int g = qMin(255, qRound(0.5*(g1+g2))); int b = qMin(255, qRound(0.5*(b1+b2)));*/ /*int a = qMin(255, qRound((1.0*a1+0.32*a2))); int r = qMin(255, qRound((1.0*r1+0.32*r2))); int g = qMin(255, qRound((1.0*g1+0.32*g2))); int b = qMin(255, qRound((1.0*b1+0.32*b2)));*/ QRgb mix = qRgba(r, g, b, a); /*qDebug() << "------"; qDebug() << r1 << g1 << b1 << a1; qDebug() << r2 << g2 << b2 << a2; qDebug() << r << g << b << a; qDebug() << qRed(mix) << qGreen(mix) << qBlue(mix) << qAlpha(mix);*/ //QRgb mix = qRgba(r2, g2, b2, a); if (a2 != 0) image->setPixel(offset.x()+x,offset.y()+y, mix); } } }
quint32 Layer::_getMaskColor() const { QRgb rgbCol = qRgba( 255,255,255,255); return rgbCol; }
QRgb BitmapImage::pixel(QPoint P) { QRgb result = qRgba(0,0,0,0); // black if ( boundaries.contains( P ) ) result = image->pixel(P - topLeft()); return result; }
QImage* QgsPieDiagramFactory::createDiagram( int size, const QgsFeature& f, const QgsRenderContext& renderContext ) const { QgsAttributeMap dataValues = f.attributeMap(); double sizeScaleFactor = diagramSizeScaleFactor( renderContext ); //create transparent QImage int imageSideLength = size * sizeScaleFactor * renderContext.rasterScaleFactor() + 2 * mMaximumPenWidth + 2 * mMaximumGap; QImage* diagramImage = new QImage( QSize( imageSideLength, imageSideLength ), QImage::Format_ARGB32_Premultiplied ); diagramImage->fill( qRgba( 0, 0, 0, 0 ) ); //transparent background QPainter p; p.begin( diagramImage ); p.setRenderHint( QPainter::Antialiasing ); p.setPen( Qt::NoPen ); //calculate sum of data values double sum = 0; QList<double> valueList; //cash the values to use them in drawing later QgsAttributeMap::const_iterator value_it; QList<QgsDiagramCategory>::const_iterator it = mCategories.constBegin(); for ( ; it != mCategories.constEnd(); ++it ) { value_it = dataValues.find( it->propertyIndex() ); valueList.push_back( value_it->toDouble() ); if ( value_it != dataValues.constEnd() ) { sum += value_it->toDouble(); } } if ( doubleNear( sum, 0.0 ) ) { p.end(); delete diagramImage; return 0; } //draw pies int totalAngle = 0; int currentAngle, currentGap; int xGapOffset = 0; int yGapOffset = 0; QList<QgsDiagramCategory>::const_iterator category_it = mCategories.constBegin(); QList<double>::const_iterator valueList_it = valueList.constBegin(); for ( ; category_it != mCategories.constEnd() && valueList_it != valueList.constEnd(); ++category_it, ++valueList_it ) { p.setPen( category_it->pen() ); currentAngle = ( int )(( *valueList_it ) / sum * 360 * 16 ); p.setBrush( category_it->brush() ); xGapOffset = 0; yGapOffset = 0; currentGap = category_it->gap(); if ( currentGap != 0 ) { //qt angles are degrees*16 gapOffsetsForPieSlice( currentGap, totalAngle + currentAngle / 2, xGapOffset, yGapOffset ); } p.drawPie( mMaximumPenWidth * renderContext.rasterScaleFactor() + mMaximumGap + xGapOffset, mMaximumPenWidth * renderContext.rasterScaleFactor() + mMaximumGap - yGapOffset, sizeScaleFactor * renderContext.rasterScaleFactor() * size, sizeScaleFactor * renderContext.rasterScaleFactor() * size, totalAngle, currentAngle ); totalAngle += currentAngle; } p.end(); return diagramImage; }
static void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, float screen_gamma=0.0) { if (screen_gamma != 0.0 && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) { double file_gamma; png_get_gAMA(png_ptr, info_ptr, &file_gamma); png_set_gamma(png_ptr, screen_gamma, file_gamma); } png_uint_32 width; png_uint_32 height; int bit_depth; int color_type; png_bytep trans_alpha = 0; png_color_16p trans_color_p = 0; int num_trans; png_colorp palette = 0; int num_palette; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); png_set_interlace_handling(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY) { // Black & White or 8-bit grayscale if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) { png_set_invert_mono(png_ptr); png_read_update_info(png_ptr, info_ptr); if (image.size() != QSize(width, height) || image.format() != QImage::Format_Mono) { image = QImage(width, height, QImage::Format_Mono); if (image.isNull()) return; } image.setColorCount(2); image.setColor(1, qRgb(0,0,0)); image.setColor(0, qRgb(255,255,255)); } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_expand(png_ptr); png_set_strip_16(png_ptr); png_set_gray_to_rgb(png_ptr); if (image.size() != QSize(width, height) || image.format() != QImage::Format_ARGB32) { image = QImage(width, height, QImage::Format_ARGB32); if (image.isNull()) return; } if (QSysInfo::ByteOrder == QSysInfo::BigEndian) png_set_swap_alpha(png_ptr); png_read_update_info(png_ptr, info_ptr); } else { if (bit_depth == 16) png_set_strip_16(png_ptr); else if (bit_depth < 8) png_set_packing(png_ptr); int ncols = bit_depth < 8 ? 1 << bit_depth : 256; png_read_update_info(png_ptr, info_ptr); if (image.size() != QSize(width, height) || image.format() != QImage::Format_Indexed8) { image = QImage(width, height, QImage::Format_Indexed8); if (image.isNull()) return; } image.setColorCount(ncols); for (int i=0; i<ncols; i++) { int c = i*255/(ncols-1); image.setColor(i, qRgba(c,c,c,0xff)); } if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_color_p) { const int g = trans_color_p->gray; if (g < ncols) { image.setColor(g, 0); } } } } else if (color_type == PNG_COLOR_TYPE_PALETTE && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) && num_palette <= 256) { // 1-bit and 8-bit color if (bit_depth != 1) png_set_packing(png_ptr); png_read_update_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); QImage::Format format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8; if (image.size() != QSize(width, height) || image.format() != format) { image = QImage(width, height, format); if (image.isNull()) return; } png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); image.setColorCount(num_palette); int i = 0; if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_alpha) { while (i < num_trans) { image.setColor(i, qRgba( palette[i].red, palette[i].green, palette[i].blue, trans_alpha[i] ) ); i++; } } while (i < num_palette) { image.setColor(i, qRgba( palette[i].red, palette[i].green, palette[i].blue, 0xff ) ); i++; } } else { // 32-bit if (bit_depth == 16) png_set_strip_16(png_ptr); png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); QImage::Format format = QImage::Format_ARGB32; // Only add filler if no alpha, or we can get 5 channel data. if (!(color_type & PNG_COLOR_MASK_ALPHA) && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_filler(png_ptr, 0xff, QSysInfo::ByteOrder == QSysInfo::BigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER); // We want 4 bytes, but it isn't an alpha channel format = QImage::Format_RGB32; } if (image.size() != QSize(width, height) || image.format() != format) { image = QImage(width, height, format); if (image.isNull()) return; } if (QSysInfo::ByteOrder == QSysInfo::BigEndian) png_set_swap_alpha(png_ptr); png_read_update_info(png_ptr, info_ptr); } // Qt==ARGB==Big(ARGB)==Little(BGRA) if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { png_set_bgr(png_ptr); } }
// Draw a line of text in the given position within the image. // It would be nice to be able to use TTFFont for this but it doesn't provide // what we want. void MHIText::AddText(int x, int y, const QString &str, MHRgba colour) { if (!m_parent->IsFaceLoaded()) return; FT_Face face = m_parent->GetFontFace(); FT_Error error = FT_Set_Char_Size(face, 0, Point2FT(m_fontsize), FONT_WIDTHRES, FONT_HEIGHTRES); // X positions are computed to 64ths and rounded. // Y positions are in pixels int posX = Point2FT(x); int pixelY = y; FT_Bool useKerning = FT_HAS_KERNING(face); FT_UInt previous = 0; int len = str.length(); for (int n = 0; n < len; n++) { // Load the glyph. QChar ch = str[n]; FT_UInt glyphIndex = FT_Get_Char_Index(face, ch.unicode()); if (glyphIndex == 0) { previous = 0; continue; } if (useKerning && previous != 0) { FT_Vector delta; FT_Get_Kerning(face, previous, glyphIndex, FT_KERNING_DEFAULT, &delta); posX += delta.x; } error = FT_Load_Glyph(face, glyphIndex, FT_LOAD_RENDER); if (error) continue; // ignore errors FT_GlyphSlot slot = face->glyph; if (slot->format != FT_GLYPH_FORMAT_BITMAP) continue; // Problem if ((enum FT_Pixel_Mode_)slot->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY) continue; unsigned char *source = slot->bitmap.buffer; // Get the origin for the bitmap int baseX = FT2Point(posX) + slot->bitmap_left; int baseY = pixelY - slot->bitmap_top; // Copy the bitmap into the image. for (int i = 0; i < slot->bitmap.rows; i++) { for (int j = 0; j < slot->bitmap.width; j++) { int greyLevel = source[j]; // Set the pixel to the specified colour but scale its // brightness according to the grey scale of the pixel. int red = colour.red(); int green = colour.green(); int blue = colour.blue(); int alpha = colour.alpha() * greyLevel / slot->bitmap.num_grays; int xBit = j + baseX; int yBit = i + baseY; // The bits ought to be inside the bitmap but // I guess there's the possibility // that rounding might put it outside. if (xBit >= 0 && xBit < m_width && yBit >= 0 && yBit < m_height) { m_image.setPixel(xBit, yBit, qRgba(red, green, blue, alpha)); } } source += slot->bitmap.pitch; } posX += slot->advance.x; previous = glyphIndex; } }
QImage numpyToQImage(const Numpy2DObj& imgdata, const Numpy2DIntObj &colors, bool forcetrans) { // make format use alpha transparency if required const int numcolors = colors.dims[0]; if ( colors.dims[1] != 4 ) throw "4 columns required in colors array"; if ( numcolors < 1 ) throw "at least 1 color required"; const int numbands = numcolors-1; const int xw = imgdata.dims[1]; const int yw = imgdata.dims[0]; // if the first value in the color is -1 then switch to jumping mode const bool jumps = colors(0,0) == -1; QImage::Format format = QImage::Format_RGB32; if( forcetrans ) format = QImage::Format_ARGB32; else { for(int i = 0; i < numcolors; ++i) { if( colors(i, 3) != 255 ) format = QImage::Format_ARGB32; } } // make image QImage img(xw, yw, format); // iterate over input pixels for(int y=0; y<yw; ++y) { // direction of images is different for qt and numpy image QRgb* scanline = reinterpret_cast<QRgb*>(img.scanLine(yw-y-1)); for(int x=0; x<xw; ++x) { double val = imgdata(x, y); // output color int b, g, r, a; if( ! isFinite(val) ) { // transparent b = g = r = a = 0; } else { val = clipval(val, 0., 1.); if( jumps ) { // jumps between colours in discrete mode // (ignores 1st color, which signals this mode) const int band = clipval(int(val*(numcolors-1))+1, 1, numcolors-1); b = colors(0, band); g = colors(1, band); r = colors(2, band); a = colors(3, band); } else { // do linear interpolation between bands // make sure between 0 and 1 const int band = clipval(int(val*numbands), 0, numbands-1); const double delta = val*numbands - band; // ensure we don't read beyond where we should const int band2 = min(band + 1, numbands); const double delta1 = 1.-delta; b = int(delta1*colors(0, band) + delta *colors(0, band2)); g = int(delta1*colors(1, band) + delta *colors(1, band2)); r = int(delta1*colors(2, band) + delta *colors(2, band2)); a = int(delta1*colors(3, band) + delta *colors(3, band2)); } } *(scanline+x) = qRgba(r, g, b, a); } } return img; }
// Based on the Bresenham line drawing algorithm but extended to draw // thick lines. void MHIDLA::DrawLineSub(int x1, int y1, int x2, int y2, bool swapped) { QRgb colour = qRgba(m_lineColour.red(), m_lineColour.green(), m_lineColour.blue(), m_lineColour.alpha()); int dx = x2-x1, dy = abs(y2-y1); int yStep = y2 >= y1 ? 1 : -1; // Adjust the starting positions to take account of the // line width. int error2 = dx/2; for (int k = 0; k < m_lineWidth/2; k++) { y1--; y2--; error2 += dy; if (error2*2 > dx) { error2 -= dx; x1 += yStep; x2 += yStep; } } // Main loop int y = y1; int error = dx/2; for (int x = x1; x <= x2; x++) // Include both endpoints { error2 = dx/2; int j = 0; // Inner loop also uses the Bresenham algorithm to draw lines // perpendicular to the principal direction. for (int i = 0; i < m_lineWidth; i++) { if (swapped) { if (x+j >= 0 && y+i >= 0 && y+i < m_width && x+j < m_height) m_image.setPixel(y+i, x+j, colour); } else { if (x+j >= 0 && y+i >= 0 && x+j < m_width && y+i < m_height) m_image.setPixel(x+j, y+i, colour); } error2 += dy; if (error2*2 > dx) { error2 -= dx; j -= yStep; if (i < m_lineWidth-1) { // Add another pixel in this case. if (swapped) { if (x+j >= 0 && y+i >= 0 && y+i < m_width && x+j < m_height) m_image.setPixel(y+i, x+j, colour); } else { if (x+j >= 0 && y+i >= 0 && x+j < m_width && y+i < m_height) m_image.setPixel(x+j, y+i, colour); } } } } error += dy; if (error*2 > dx) { error -= dx; y += yStep; } } }
void KbPerf::lightIndicator(const char* name, QRgb rgba){ int a = round(qAlpha(rgba) * _iOpacity); if(a <= 0) return; light()->setIndicator(name, qRgba(qRed(rgba), qGreen(rgba), qBlue(rgba), a)); }
void MHIDLA::DrawPoly(bool isFilled, int nPoints, const int *xArray, const int *yArray) { if (nPoints < 2) return; if (isFilled) { QVector <lineSeg> lineArray(nPoints); int nLines = 0; // Initialise the line segment array. Include all lines // apart from horizontal. Close the polygon by starting // with the last point in the array. int lastX = xArray[nPoints-1]; // Last point int lastY = yArray[nPoints-1]; int yMin = lastY, yMax = lastY; for (int k = 0; k < nPoints; k++) { int thisX = xArray[k]; int thisY = yArray[k]; if (lastY != thisY) { if (lastY > thisY) { lineArray[nLines].yBottom = thisY; lineArray[nLines].yTop = lastY; lineArray[nLines].xBottom = thisX; } else { lineArray[nLines].yBottom = lastY; lineArray[nLines].yTop = thisY; lineArray[nLines].xBottom = lastX; } lineArray[nLines++].slope = (float)(thisX-lastX) / (float)(thisY-lastY); } if (thisY < yMin) yMin = thisY; if (thisY > yMax) yMax = thisY; lastX = thisX; lastY = thisY; } // Find the intersections of each line in the line segment array // with the scan line. Because UK MHEG says that figures should be // convex we only need to consider two intersections. QRgb fillColour = qRgba(m_fillColour.red(), m_fillColour.green(), m_fillColour.blue(), m_fillColour.alpha()); for (int y = yMin; y < yMax; y++) { int crossings = 0, xMin = 0, xMax = 0; for (int l = 0; l < nLines; l++) { if (y >= lineArray[l].yBottom && y < lineArray[l].yTop) { int x = (int)round((float)(y - lineArray[l].yBottom) * lineArray[l].slope) + lineArray[l].xBottom; if (crossings == 0 || x < xMin) xMin = x; if (crossings == 0 || x > xMax) xMax = x; crossings++; } } if (crossings == 2) { for (int x = xMin; x <= xMax; x++) m_image.setPixel(x, y, fillColour); } } // Draw the boundary int lastXpoint = xArray[nPoints-1]; // Last point int lastYpoint = yArray[nPoints-1]; for (int i = 0; i < nPoints; i++) { DrawLine(xArray[i], yArray[i], lastXpoint, lastYpoint); lastXpoint = xArray[i]; lastYpoint = yArray[i]; } } else // PolyLine - draw lines between the points but don't close it. { for (int i = 1; i < nPoints; i++) { DrawLine(xArray[i], yArray[i], xArray[i-1], yArray[i-1]); } } }
/** * Clear the canvas. */ void GLWidget3D::clearSketch() { sketch.fill(qRgba(255, 255, 255, 255)); update(); }
QgsRasterBlock * QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle const & extent, int width, int height, QgsRasterBlockFeedback* feedback ) { QgsRasterBlock *outputBlock = new QgsRasterBlock(); if ( !mInput || mNColors == 0 ) { return outputBlock; } QgsRasterBlock *inputBlock = mInput->block( bandNo, extent, width, height, feedback ); if ( !inputBlock || inputBlock->isEmpty() ) { QgsDebugMsg( "No raster data!" ); delete inputBlock; return outputBlock; } double currentOpacity = mOpacity; //rendering is faster without considering user-defined transparency bool hasTransparency = usesTransparency(); QgsRasterBlock *alphaBlock = nullptr; if ( mAlphaBand > 0 && mAlphaBand != mBand ) { alphaBlock = mInput->block( mAlphaBand, extent, width, height, feedback ); if ( !alphaBlock || alphaBlock->isEmpty() ) { delete inputBlock; delete alphaBlock; return outputBlock; } } else if ( mAlphaBand == mBand ) { alphaBlock = inputBlock; } if ( !outputBlock->reset( Qgis::ARGB32_Premultiplied, width, height ) ) { delete inputBlock; delete alphaBlock; return outputBlock; } QRgb myDefaultColor = NODATA_COLOR; //use direct data access instead of QgsRasterBlock::setValue //because of performance unsigned int* outputData = ( unsigned int* )( outputBlock->bits() ); qgssize rasterSize = ( qgssize )width * height; for ( qgssize i = 0; i < rasterSize; ++i ) { if ( inputBlock->isNoData( i ) ) { outputData[i] = myDefaultColor; continue; } int val = ( int ) inputBlock->value( i ); if ( !hasTransparency ) { outputData[i] = mColors[val]; } else { currentOpacity = mOpacity; if ( mRasterTransparency ) { currentOpacity = mRasterTransparency->alphaValue( val, mOpacity * 255 ) / 255.0; } if ( mAlphaBand > 0 ) { currentOpacity *= alphaBlock->value( i ) / 255.0; } QColor currentColor = QColor( mColors[val] ); outputData[i] = qRgba( currentOpacity * currentColor.red(), currentOpacity * currentColor.green(), currentOpacity * currentColor.blue(), currentOpacity * 255 ); } } delete inputBlock; if ( mAlphaBand > 0 && mBand != mAlphaBand ) { delete alphaBlock; } return outputBlock; }
void tst_QColor::setRgb() { QColor color; for (int A = 0; A <= USHRT_MAX; ++A) { { // 0-255 int a = A >> 8; QRgb rgb = qRgba(0, 0, 0, a); color.setRgb(0, 0, 0, a); QCOMPARE(color.alpha(), a); QCOMPARE(color.rgb(), qRgb(0, 0, 0)); color.setRgb(rgb); QCOMPARE(color.alpha(), 255); QCOMPARE(color.rgb(), qRgb(0, 0, 0)); int r, g, b, a2; color.setRgb(0, 0, 0, a); color.getRgb(&r, &g, &b, &a2); QCOMPARE(a2, a); QColor c(0, 0, 0); c.setAlpha(a); QCOMPARE(c.alpha(), a); } { // 0.0-1.0 qreal a = A / qreal(USHRT_MAX); color.setRgbF(0.0, 0.0, 0.0, a); QCOMPARE(color.alphaF(), a); qreal r, g, b, a2; color.getRgbF(&r, &g, &b, &a2); QCOMPARE(a2, a); QColor c(0, 0, 0); c.setAlphaF(a); QCOMPARE(c.alphaF(), a); } } for (int R = 0; R <= USHRT_MAX; ++R) { { // 0-255 int r = R >> 8; QRgb rgb = qRgb(r, 0, 0); color.setRgb(r, 0, 0); QCOMPARE(color.red(), r); QCOMPARE(color.rgb(), rgb); color.setRgb(rgb); QCOMPARE(color.red(), r); QCOMPARE(color.rgb(), rgb); int r2, g, b, a; color.getRgb(&r2, &g, &b, &a); QCOMPARE(r2, r); } { // 0.0-1.0 qreal r = R / qreal(USHRT_MAX); color.setRgbF(r, 0.0, 0.0); QCOMPARE(color.redF(), r); qreal r2, g, b, a; color.getRgbF(&r2, &g, &b, &a); QCOMPARE(r2, r); } } for (int G = 0; G <= USHRT_MAX; ++G) { { // 0-255 int g = G >> 8; QRgb rgb = qRgb(0, g, 0); color.setRgb(0, g, 0); QCOMPARE(color.green(), g); QCOMPARE(color.rgb(), rgb); color.setRgb(rgb); QCOMPARE(color.green(), g); QCOMPARE(color.rgb(), rgb); int r, g2, b, a; color.getRgb(&r, &g2, &b, &a); QCOMPARE(g2, g); } { // 0.0-1.0 qreal g = G / qreal(USHRT_MAX); color.setRgbF(0.0, g, 0.0); QCOMPARE(color.greenF(), g); qreal r, g2, b, a; color.getRgbF(&r, &g2, &b, &a); QCOMPARE(g2, g); } } for (int B = 0; B <= USHRT_MAX; ++B) { { // 0-255 int b = B >> 8; QRgb rgb = qRgb(0, 0, b); color.setRgb(0, 0, b); QCOMPARE(color.blue(), b); QCOMPARE(color.rgb(), rgb); color.setRgb(rgb); QCOMPARE(color.blue(), b); QCOMPARE(color.rgb(), rgb); int r, g, b2, a; color.getRgb(&r, &g, &b2, &a); QCOMPARE(b2, b); } { // 0.0-1.0 qreal b = B / qreal(USHRT_MAX); color.setRgbF(0.0, 0.0, b); QCOMPARE(color.blueF(), b); qreal r, g, b2, a; color.getRgbF(&r, &g, &b2, &a); QCOMPARE(b2, b); } } }
/** * @fn appliquer Applique l'inpainting sur une image * @param init image initiale, masque image correspodant au masque, out image resultat, * _iteration nb d'iterations a effectuer, dt delta t */ void CTschumperle::appliquer(CImage *init, CImage *masque, CImage *out, float _iteration, float dt) { this->progressbar->setMaximum(_iteration);//initialise la progressbar CImageDouble *I_tmp = new CImageDouble(init); CImageDouble *Out_tmp = new CImageDouble(init); /*Out_tmp->Copy(init);*/ for (int y = 0; y < init->height(); ++y) { for (int x = 0; x < init->width(); ++x) { if (masque->getPixel(x, y) == qRgba(0, 0, 0, 255)) { Out_tmp->setRedPixel(x, y, 0.0); Out_tmp->setGreenPixel(x, y, 0.0); Out_tmp->setBluePixel(x, y, 0.0); } } } for (int it = 0; it < _iteration; ++it) { this->progressbar->setValue(this->progressbar->value()+1);//incremente la progressbar I_tmp->Copy(Out_tmp); for (int j = 0; j < masque->height(); ++j) { for (int i = 0; i < masque->width(); ++i) { if (masque->getPixel(i, j) == qRgba(0, 0, 0, 255)) { /*Calcul de la hessienne pr un pixel du masque */ double *H_r = CHessian::GetHessian(I_tmp, i, j, 0); double *H_g = CHessian::GetHessian(I_tmp, i, j, 1); double *H_b = CHessian::GetHessian(I_tmp, i, j, 2); /*Calcul du tenseur de diffusion*/ CDiffTensor T = CDiffTensor(I_tmp, i, j); double *D_r = T.GetDiffTensor_r(); double *D_g = T.GetDiffTensor_g(); double *D_b = T.GetDiffTensor_b();/*AJOUTER GAUSSIENE SUR LES MATRICES 'D' */ /*Calcul de la matrice D.H*/ double Mat_res_r[4]; double Mat_res_g[4]; double Mat_res_b[4]; Mat_res_r[0] = D_r[0]*H_r[0]+D_r[1]*H_r[2]; Mat_res_r[1] = D_r[0]*H_r[1]+D_r[1]*H_r[3]; Mat_res_r[2] = D_r[2]*H_r[0]+D_r[3]*H_r[2]; Mat_res_r[3] = D_r[2]*H_r[1]+D_r[3]*H_r[3]; Mat_res_g[0] = D_g[0]*H_g[0]+D_g[1]*H_g[2]; Mat_res_g[1] = D_g[0]*H_g[1]+D_g[1]*H_g[3]; Mat_res_g[2] = D_g[2]*H_g[0]+D_g[3]*H_g[2]; Mat_res_g[3] = D_g[2]*H_g[1]+D_g[3]*H_g[3]; Mat_res_b[0] = D_b[0]*H_b[0]+D_b[1]*H_b[2]; Mat_res_b[1] = D_b[0]*H_b[1]+D_b[1]*H_b[3]; Mat_res_b[2] = D_b[2]*H_b[0]+D_b[3]*H_b[2]; Mat_res_b[3] = D_b[2]*H_b[1]+D_b[3]*H_b[3]; /*qDebug() << "DiffTensor R: [" << D_r[0] << "," << D_r[1] << "," << D_r[2] << "," << D_r[3] << "]\n" << "Hessian R: [" << H_r[0] << "," << H_r[1] << "," << H_r[2] << "," << H_r[3] << "]\n" << "MatRes R: [" << Mat_res_r[0] << "," << Mat_res_r[1] << "," << Mat_res_r[2] << "," << Mat_res_r[3] << "]\n" << "DiffTensor G: [" << D_g[0] << "," << D_g[1] << "," << D_g[2] << "," << D_g[3] << "]\n" << "Hessian G: [" << H_g[0] << "," << H_g[1] << "," << H_g[2] << "," << H_g[3] << "]\n" << "MatRes G: [" << Mat_res_g[0] << "," << Mat_res_g[1] << "," << Mat_res_g[2] << "," << Mat_res_g[3] << "]\n" << "DiffTensor B: [" << D_b[0] << "," << D_b[1] << "," << D_b[2] << "," << D_b[3] << "]\n" << "Hessian B: [" << H_b[0] << "," << H_b[1] << "," << H_b[2] << "," << H_b[3] << "]\n" << "MatRes B: [" << Mat_res_b[0] << "," << Mat_res_b[1] << "," << Mat_res_b[2] << "," << Mat_res_b[3] << "]\n"; qDebug() << "Val px R: I_tmp->getRedPixel(i, j) : " << I_tmp->getRedPixel(i, j) << " + dt*(D.H) : " << dt*(Mat_res_r[0]+Mat_res_r[3]) << " = " << (I_tmp->getRedPixel(i, j)+(dt*(Mat_res_r[0]+Mat_res_r[3]))) << "\nVal px G: I_tmp->getGreenPixel(i, j) : " << I_tmp->getGreenPixel(i, j) << " + dt*(D.H) : " << dt*(Mat_res_g[0]+Mat_res_g[3]) << " = " << (I_tmp->getGreenPixel(i, j)+(dt*(Mat_res_g[0]+Mat_res_g[3]))) << "\nVal px B: I_tmp->getBluePixel(i, j) : " << I_tmp->getBluePixel(i, j) << " + dt*(D.H) : " << dt*(Mat_res_b[0]+Mat_res_b[3]) << " = " << (I_tmp->getBluePixel(i, j)+(dt*(Mat_res_b[0]+Mat_res_b[3])));*/ /*Calcul de la valeur a ajouter au pixel avec dt*trace(DH)*/ //out->setPixel(i, j, qRgb(I_tmp->getRedPixel(i, j)+(dt*(Mat_res_r[0]+Mat_res_r[3])), I_tmp->getGreenPixel(i, j)+(dt*(Mat_res_g[0]+Mat_res_g[3])), I_tmp->getBluePixel(i, j)+(dt*(Mat_res_b[0]+Mat_res_b[3])))); if ((dt*(Mat_res_r[0]+Mat_res_r[3])) == (dt*(Mat_res_r[0]+Mat_res_r[3]))) Out_tmp->setRedPixel(i, j, I_tmp->getRedPixel(i, j)+(dt*(Mat_res_r[0]+Mat_res_r[3]))); if ((dt*(Mat_res_g[0]+Mat_res_g[3])) == (dt*(Mat_res_g[0]+Mat_res_g[3]))) Out_tmp->setGreenPixel(i, j, I_tmp->getGreenPixel(i, j)+(dt*(Mat_res_g[0]+Mat_res_g[3]))); if ((dt*(Mat_res_b[0]+Mat_res_b[3])) == (dt*(Mat_res_b[0]+Mat_res_b[3]))) Out_tmp->setBluePixel(i, j, I_tmp->getBluePixel(i, j)+(dt*(Mat_res_b[0]+Mat_res_b[3]))); //qDebug() << "\n______________________________________________________\n"; delete H_r; delete H_g; delete H_b; delete D_r; delete D_g; delete D_b; } } } } out->Copy(Out_tmp->getQimage()); delete I_tmp; delete Out_tmp; }
// Stack Blur Algorithm by Mario Klingemann <*****@*****.**> // fixed to handle alpha channel correctly by Zack Rusin void fastbluralpha(QImage &img, int radius) { if (radius < 1) { return; } QRgb *pix = (QRgb*)img.bits(); int w = img.width(); int h = img.height(); int wm = w - 1; int hm = h - 1; int wh = w * h; int div = radius + radius + 1; int *r = new int[wh]; int *g = new int[wh]; int *b = new int[wh]; int *a = new int[wh]; int rsum, gsum, bsum, asum, x, y, i, yp, yi, yw; QRgb p; int *vmin = new int[qMax(w, h)]; int divsum = (div + 1) >> 1; divsum *= divsum; int *dv = new int[256*divsum]; for (i = 0; i < 256*divsum; ++i) { dv[i] = (i / divsum); } yw = yi = 0; int **stack = new int*[div]; for (int i = 0; i < div; ++i) { stack[i] = new int[4]; } int stackpointer; int stackstart; int *sir; int rbs; int r1 = radius + 1; int routsum, goutsum, boutsum, aoutsum; int rinsum, ginsum, binsum, ainsum; for (y = 0; y < h; ++y) { rinsum = ginsum = binsum = ainsum = routsum = goutsum = boutsum = aoutsum = rsum = gsum = bsum = asum = 0; for (i = - radius; i <= radius; ++i) { p = pix[yi+qMin(wm, qMax(i, 0))]; sir = stack[i+radius]; sir[0] = qRed(p); sir[1] = qGreen(p); sir[2] = qBlue(p); sir[3] = qAlpha(p); rbs = r1 - abs(i); rsum += sir[0] * rbs; gsum += sir[1] * rbs; bsum += sir[2] * rbs; asum += sir[3] * rbs; if (i > 0) { rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; ainsum += sir[3]; } else { routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; aoutsum += sir[3]; } } stackpointer = radius; for (x = 0; x < w; ++x) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; a[yi] = dv[asum]; rsum -= routsum; gsum -= goutsum; bsum -= boutsum; asum -= aoutsum; stackstart = stackpointer - radius + div; sir = stack[stackstart%div]; routsum -= sir[0]; goutsum -= sir[1]; boutsum -= sir[2]; aoutsum -= sir[3]; if (y == 0) { vmin[x] = qMin(x + radius + 1, wm); } p = pix[yw+vmin[x]]; sir[0] = qRed(p); sir[1] = qGreen(p); sir[2] = qBlue(p); sir[3] = qAlpha(p); rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; ainsum += sir[3]; rsum += rinsum; gsum += ginsum; bsum += binsum; asum += ainsum; stackpointer = (stackpointer + 1) % div; sir = stack[(stackpointer)%div]; routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; aoutsum += sir[3]; rinsum -= sir[0]; ginsum -= sir[1]; binsum -= sir[2]; ainsum -= sir[3]; ++yi; } yw += w; } for (x = 0; x < w; ++x) { rinsum = ginsum = binsum = ainsum = routsum = goutsum = boutsum = aoutsum = rsum = gsum = bsum = asum = 0; yp = - radius * w; for (i = -radius; i <= radius; ++i) { yi = qMax(0, yp) + x; sir = stack[i+radius]; sir[0] = r[yi]; sir[1] = g[yi]; sir[2] = b[yi]; sir[3] = a[yi]; rbs = r1 - abs(i); rsum += r[yi] * rbs; gsum += g[yi] * rbs; bsum += b[yi] * rbs; asum += a[yi] * rbs; if (i > 0) { rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; ainsum += sir[3]; } else { routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; aoutsum += sir[3]; } if (i < hm) { yp += w; } } yi = x; stackpointer = radius; for (y = 0; y < h; ++y) { pix[yi] = qRgba(dv[rsum], dv[gsum], dv[bsum], dv[asum]); rsum -= routsum; gsum -= goutsum; bsum -= boutsum; asum -= aoutsum; stackstart = stackpointer - radius + div; sir = stack[stackstart%div]; routsum -= sir[0]; goutsum -= sir[1]; boutsum -= sir[2]; aoutsum -= sir[3]; if (x == 0) { vmin[y] = qMin(y + r1, hm) * w; } p = x + vmin[y]; sir[0] = r[p]; sir[1] = g[p]; sir[2] = b[p]; sir[3] = a[p]; rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; ainsum += sir[3]; rsum += rinsum; gsum += ginsum; bsum += binsum; asum += ainsum; stackpointer = (stackpointer + 1) % div; sir = stack[stackpointer]; routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; aoutsum += sir[3]; rinsum -= sir[0]; ginsum -= sir[1]; binsum -= sir[2]; ainsum -= sir[3]; yi += w; } } delete [] r; delete [] g; delete [] b; delete [] a; delete [] vmin; delete [] dv; for (int i = 0; i < div; ++i) { delete [] stack[i]; } delete [] stack; }
bool KoPattern::init(QByteArray& bytes) { int dataSize = bytes.size(); const char* data = bytes.constData(); // load Gimp patterns GimpPatternHeader bh; qint32 k; char* name; if ((int)sizeof(GimpPatternHeader) > dataSize) { return false; } memcpy(&bh, data, sizeof(GimpPatternHeader)); bh.header_size = qFromBigEndian(bh.header_size); bh.version = qFromBigEndian(bh.version); bh.width = qFromBigEndian(bh.width); bh.height = qFromBigEndian(bh.height); bh.bytes = qFromBigEndian(bh.bytes); bh.magic_number = qFromBigEndian(bh.magic_number); if ((int)bh.header_size > dataSize || bh.header_size == 0) { return false; } int size = bh.header_size - sizeof(GimpPatternHeader); name = new char[size]; memcpy(name, data + sizeof(GimpPatternHeader), size); if (name[size - 1]) { delete[] name; return false; } // size -1 so we don't add the end 0 to the QString... setName(QString::fromLatin1(name, size -1)); delete[] name; if (bh.width == 0 || bh.height == 0) { return false; } QImage::Format imageFormat; if (bh.bytes == 1 || bh.bytes == 3) { imageFormat = QImage::Format_RGB32; } else { imageFormat = QImage::Format_ARGB32; } QImage pattern = QImage(bh.width, bh.height, imageFormat); if (pattern.isNull()) { return false; } k = bh.header_size; if (bh.bytes == 1) { // Grayscale qint32 val; for (quint32 y = 0; y < bh.height; ++y) { QRgb* pixels = reinterpret_cast<QRgb*>( pattern.scanLine(y) ); for (quint32 x = 0; x < bh.width; ++x, ++k) { if (k > dataSize) { qWarning() << "failed to load grayscale pattern" << filename(); return false; } val = data[k]; pixels[x] = qRgb(val, val, val); } } // It was grayscale, so make the pattern as small as possible // by converting it to Indexed8 pattern = pattern.convertToFormat(QImage::Format_Indexed8); } else if (bh.bytes == 2) { // Grayscale + A qint32 val; qint32 alpha; for (quint32 y = 0; y < bh.height; ++y) { QRgb* pixels = reinterpret_cast<QRgb*>( pattern.scanLine(y) ); for (quint32 x = 0; x < bh.width; ++x, ++k) { if (k + 2 > dataSize) { qWarning() << "failed to load grayscale +_ alpha pattern" << filename(); return false; } val = data[k]; alpha = data[k++]; pixels[x] = qRgba(val, val, val, alpha); } } } else if (bh.bytes == 3) { // RGB without alpha for (quint32 y = 0; y < bh.height; ++y) { QRgb* pixels = reinterpret_cast<QRgb*>( pattern.scanLine(y) ); for (quint32 x = 0; x < bh.width; ++x) { if (k + 3 > dataSize) { qWarning() << "failed to load RGB pattern" << filename(); return false; } pixels[x] = qRgb(data[k], data[k + 1], data[k + 2]); k += 3; } } } else if (bh.bytes == 4) { // Has alpha for (quint32 y = 0; y < bh.height; ++y) { QRgb* pixels = reinterpret_cast<QRgb*>( pattern.scanLine(y) ); for (quint32 x = 0; x < bh.width; ++x) { if (k + 4 > dataSize) { qWarning() << "failed to load RGB + Alpha pattern" << filename(); return false; } pixels[x] = qRgba(data[k], data[k + 1], data[k + 2], data[k + 3]); k += 4; } } } else { return false; } if (pattern.isNull()) { return false; } setPatternImage(pattern); setValid(true); return true; }