@@ -488,10 +488,11 @@ void QgsHttpRequestHandler::medianCut( QVector<QRgb>& colorTable, int nColors, c
488
488
}
489
489
490
490
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 ();
493
493
494
494
// split boxes until number of boxes == nColors or all the boxes have color count 1
495
+ bool allColorsMapped = false ;
495
496
while ( colorBoxMap.size () < nColors )
496
497
{
497
498
// 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
502
503
if ( colorBoxMapIt.value ().size () > 1 )
503
504
{
504
505
splitColorBox ( colorBoxMapIt.value (), colorBoxMap, colorBoxMapIt );
505
- continue ;
506
+ break ;
506
507
}
507
508
if ( colorBoxMapIt == colorBoxMap.begin () )
508
509
{
510
+ allColorsMapped = true ;
509
511
break ;
510
512
}
511
513
}
514
+
515
+ if ( allColorsMapped )
516
+ {
517
+ break ;
518
+ }
519
+ else
520
+ {
521
+ continue ;
522
+ }
512
523
}
513
524
525
+ bool debug = true ; // only for breakpoint
526
+
514
527
// todo: evaluate the colors of the final boxes
515
528
}
516
529
@@ -543,8 +556,161 @@ void QgsHttpRequestHandler::imageColors( QHash<QRgb, int>& colors, const QImage&
543
556
void QgsHttpRequestHandler::splitColorBox ( QgsColorBox& colorBox, QgsColorBoxMap& colorBoxMap,
544
557
QMap<int , QgsColorBox>::iterator colorBoxMapIt )
545
558
{
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
+
547
576
// 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
+
548
594
// 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
+
549
619
// 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 );
550
716
}
0 commit comments