@@ -488,10 +488,11 @@ void QgsHttpRequestHandler::medianCut( QVector<QRgb>& colorTable, int nColors, c
488488 }
489489
490490 QgsColorBoxMap colorBoxMap; // QMultiMap< int, ColorBox >
491- QMap< int , QgsColorBox>::iterator colorBoxMapIt ;
492-
491+ colorBoxMap. insert ( firstBoxPixelSum, firstBox ) ;
492+ QMap< int , QgsColorBox>::iterator colorBoxMapIt = colorBoxMap. end ();
493493
494494 // split boxes until number of boxes == nColors or all the boxes have color count 1
495+ bool allColorsMapped = false ;
495496 while ( colorBoxMap.size () < nColors )
496497 {
497498 // start at the end of colorBoxMap and pick the first entry with number of colors < 1
@@ -502,15 +503,27 @@ void QgsHttpRequestHandler::medianCut( QVector<QRgb>& colorTable, int nColors, c
502503 if ( colorBoxMapIt.value ().size () > 1 )
503504 {
504505 splitColorBox ( colorBoxMapIt.value (), colorBoxMap, colorBoxMapIt );
505- continue ;
506+ break ;
506507 }
507508 if ( colorBoxMapIt == colorBoxMap.begin () )
508509 {
510+ allColorsMapped = true ;
509511 break ;
510512 }
511513 }
514+
515+ if ( allColorsMapped )
516+ {
517+ break ;
518+ }
519+ else
520+ {
521+ continue ;
522+ }
512523 }
513524
525+ bool debug = true ; // only for breakpoint
526+
514527 // todo: evaluate the colors of the final boxes
515528}
516529
@@ -543,8 +556,161 @@ void QgsHttpRequestHandler::imageColors( QHash<QRgb, int>& colors, const QImage&
543556void QgsHttpRequestHandler::splitColorBox ( QgsColorBox& colorBox, QgsColorBoxMap& colorBoxMap,
544557 QMap<int , QgsColorBox>::iterator colorBoxMapIt )
545558{
546- // todo: a,r,g,b ranges
559+
560+ if ( colorBox.size () < 2 )
561+ {
562+ return ; // need at least two colors for a split
563+ }
564+
565+ // a,r,g,b ranges
566+ int redRange = 0 ;
567+ int greenRange = 0 ;
568+ int blueRange = 0 ;
569+ int alphaRange = 0 ;
570+
571+ if ( !minMaxRange ( colorBox, redRange, greenRange, blueRange, alphaRange ) )
572+ {
573+ return ;
574+ }
575+
547576 // sort color box for a/r/g/b
577+ if ( redRange >= greenRange && redRange >= blueRange && redRange >= alphaRange )
578+ {
579+ qSort ( colorBox.begin (), colorBox.end (), redCompare );
580+ }
581+ else if ( greenRange >= redRange && greenRange >= blueRange && greenRange >= alphaRange )
582+ {
583+ qSort ( colorBox.begin (), colorBox.end (), greenCompare );
584+ }
585+ else if ( blueRange >= redRange && blueRange >= greenRange && blueRange >= alphaRange )
586+ {
587+ qSort ( colorBox.begin (), colorBox.end (), blueCompare );
588+ }
589+ else
590+ {
591+ qSort ( colorBox.begin (), colorBox.end (), alphaCompare );
592+ }
593+
548594 // get median
595+ double halfSum = colorBoxMapIt.key () / 2.0 ;
596+ int currentSum = 0 ;
597+ int currentListIndex = 0 ;
598+
599+ QgsColorBox::iterator colorBoxIt = colorBox.begin ();
600+ for ( ; colorBoxIt != colorBox.end (); ++colorBoxIt )
601+ {
602+ currentSum += colorBoxIt->second ;
603+ if ( currentSum >= halfSum )
604+ {
605+ break ;
606+ }
607+ ++currentListIndex;
608+ }
609+
610+ if ( currentListIndex > ( colorBox.size () - 2 ) ) // if the median is contained in the last color, split one item before that
611+ {
612+ --currentListIndex;
613+ }
614+ else
615+ {
616+ ++colorBoxIt; // the iterator needs to point behind the last item to remove
617+ }
618+
549619 // do split: replace old color box, insert new one
620+ QgsColorBox newColorBox1 = colorBox.mid ( 0 , currentListIndex + 1 );
621+ colorBoxMap.insert ( currentSum, newColorBox1 );
622+
623+ colorBox.erase ( colorBox.begin (), colorBoxIt );
624+ QgsColorBox newColorBox2 = colorBox;
625+ colorBoxMap.erase ( colorBoxMapIt );
626+ colorBoxMap.insert ( halfSum * 2.0 - currentSum, newColorBox2 );
627+ }
628+
629+ bool QgsHttpRequestHandler::minMaxRange ( const QgsColorBox& colorBox, int & redRange, int & greenRange, int & blueRange, int & alphaRange )
630+ {
631+ if ( colorBox.size () < 1 )
632+ {
633+ return false ;
634+ }
635+
636+ int rMin = INT_MAX ;
637+ int gMin = INT_MAX ;
638+ int bMin = INT_MAX ;
639+ int aMin = INT_MAX ;
640+ int rMax = INT_MIN ;
641+ int gMax = INT_MIN ;
642+ int bMax = INT_MIN ;
643+ int aMax = INT_MIN ;
644+
645+ int currentRed = 0 ; int currentGreen = 0 ; int currentBlue = 0 ; int currentAlpha = 0 ;
646+
647+ QgsColorBox::const_iterator colorBoxIt = colorBox.constBegin ();
648+ for ( ; colorBoxIt != colorBox.constEnd (); ++colorBoxIt )
649+ {
650+ currentRed = qRed ( colorBoxIt->first );
651+ if ( currentRed > rMax )
652+ {
653+ rMax = currentRed;
654+ }
655+ if ( currentRed < rMin )
656+ {
657+ rMin = currentRed;
658+ }
659+
660+ currentGreen = qGreen ( colorBoxIt->first );
661+ if ( currentGreen > gMax )
662+ {
663+ gMax = currentGreen;
664+ }
665+ if ( currentGreen < gMin )
666+ {
667+ gMin = currentGreen;
668+ }
669+
670+ currentBlue = qBlue ( colorBoxIt->first );
671+ if ( currentBlue > bMax )
672+ {
673+ bMax = currentBlue;
674+ }
675+ if ( currentBlue < bMin )
676+ {
677+ bMin = currentBlue;
678+ }
679+
680+ currentAlpha = qAlpha ( colorBoxIt->first );
681+ if ( currentAlpha > aMax )
682+ {
683+ aMax = currentAlpha;
684+ }
685+ if ( currentAlpha < aMin )
686+ {
687+ aMin = currentAlpha;
688+ }
689+ }
690+
691+ redRange = rMax - rMin;
692+ greenRange = gMax - gMin ;
693+ blueRange = bMax - bMin;
694+ alphaRange = aMax - aMin;
695+ return true ;
696+ }
697+
698+ bool QgsHttpRequestHandler::redCompare ( const QPair<QRgb, int >& c1, const QPair<QRgb, int >& c2 )
699+ {
700+ return qRed ( c1.first ) < qRed ( c2.first );
701+ }
702+
703+ bool QgsHttpRequestHandler::greenCompare ( const QPair<QRgb, int >& c1, const QPair<QRgb, int >& c2 )
704+ {
705+ return qGreen ( c1.first ) < qGreen ( c2.first );
706+ }
707+
708+ bool QgsHttpRequestHandler::blueCompare ( const QPair<QRgb, int >& c1, const QPair<QRgb, int >& c2 )
709+ {
710+ return qBlue ( c1.first ) < qBlue ( c2.first );
711+ }
712+
713+ bool QgsHttpRequestHandler::alphaCompare ( const QPair<QRgb, int >& c1, const QPair<QRgb, int >& c2 )
714+ {
715+ return qAlpha ( c1.first ) < qAlpha ( c2.first );
550716}
0 commit comments