# HG changeset patch # User Claus Gittinger # Date 1504036793 -7200 # Node ID 10c304b0f4db8818a18d6af05c720c8a5816ef2e # Parent 4deac40e67b02816aafeefdc672bf10a7ff27d47 #FEATURE by cg class: Color class changed: #best:ditherColorsForImage: diff -r 4deac40e67b0 -r 10c304b0f4db Color.st --- a/Color.st Tue Aug 29 20:08:35 2017 +0200 +++ b/Color.st Tue Aug 29 21:59:53 2017 +0200 @@ -3550,9 +3550,9 @@ best:numColors ditherColorsForImage:anImage "work in progress" - |bigCube boxMax numBits numGray usedColors + |cube boxMaxR boxMaxG boxMaxB numBitsR numBitsG numBitsB numGray usedColors minRed maxRed minGreen maxGreen minBlue maxBlue - boundaryColors boxesSegmented segments boxesToDo enumerateNeighbors + boundaryColors boxesAlreadySegmented segments boxesToDo enumerateNeighbors firstTry segmentColors| ((anImage photometric == #blackIs0) or:[anImage photometric == #whiteIs0]) ifTrue:[ @@ -3567,13 +3567,18 @@ ]. ]. - boxMax := 63. - numBits := 6. + numBitsR := 7. + numBitsG := 8. + numBitsB := 5. + firstTry := true. [ - "/ first, a rough cube with less precision... - bigCube := IntegerArray new:(boxMax+1)*(boxMax+1)*(boxMax+1). + boxMaxR := (1 << numBitsR) - 1. + boxMaxG := (1 << numBitsG) - 1. + boxMaxB := (1 << numBitsB) - 1. + + cube := IntegerArray new:(boxMaxR+1)*(boxMaxG+1)*(boxMaxB+1). firstTry ifTrue:[ usedColors := Set new. @@ -3591,11 +3596,11 @@ greenByte := (rgb rightShift:8) bitAnd:16rFF. blueByte := (rgb) bitAnd:16rFF. - r := redByte rightShift:(8-numBits). - g := greenByte rightShift:(8-numBits). - b := blueByte rightShift:(8-numBits). - idx := (((r * (boxMax+1))+g)*(boxMax+1))+b+1. - oldCount := bigCube at:idx. + r := redByte rightShift:(8-numBitsR). + g := greenByte rightShift:(8-numBitsG). + b := blueByte rightShift:(8-numBitsB). + idx := (((r * (boxMaxG+1))+g)*(boxMaxB+1))+b+1. + oldCount := cube at:idx. firstTry ifTrue:[ redByte < minRed ifTrue:[minRed := redByte] ifFalse:[redByte > maxRed ifTrue:[maxRed := redByte]]. @@ -3606,7 +3611,7 @@ usedColors add:rgb. ]. ]. - bigCube at:idx put:oldCount+1. + cube at:idx put:oldCount+1. ]. firstTry ifTrue:[ @@ -3642,7 +3647,7 @@ "/ "/ find and generate connected subarea box sets "/ - boxesSegmented := Set new. + boxesAlreadySegmented := Set new. segments := OrderedCollection new. boxesToDo := OrderedCollection new. @@ -3653,17 +3658,17 @@ [:rgb :aBlock| |r g b| - r := (rgb rightShift:(numBits+numBits)) bitAnd:boxMax. - g := (rgb rightShift:numBits) bitAnd:boxMax. - b := (rgb) bitAnd:boxMax. + r := (rgb rightShift:(numBitsG+numBitsB)) bitAnd:boxMaxR. + g := (rgb rightShift:numBitsB) bitAnd:boxMaxG. + b := (rgb) bitAnd:boxMaxB. r-1 to:r+1 do:[:n_r | - (n_r between:0 and:boxMax) ifTrue:[ + (n_r between:0 and:boxMaxR) ifTrue:[ g-1 to:g+1 do:[:n_g | - (n_g between:0 and:boxMax) ifTrue:[ + (n_g between:0 and:boxMaxG) ifTrue:[ b-1 to:b+1 do:[:n_b | - (n_b between:0 and:boxMax) ifTrue:[ + (n_b between:0 and:boxMaxB) ifTrue:[ ((n_r == r) and:[n_g == g and:[n_b == b]]) ifFalse:[ - aBlock value:((((n_r * (boxMax+1))+n_g)*(boxMax+1))+n_b). + aBlock value:((((n_r * (boxMaxG+1))+n_g)*(boxMaxB+1))+n_b). ] ] ] @@ -3673,14 +3678,14 @@ ]. ]. - 0 to:boxMax do:[:r | - 0 to:boxMax do:[:g | - 0 to:boxMax do:[:b | + 0 to:boxMaxR do:[:r | + 0 to:boxMaxG do:[:g | + 0 to:boxMaxB do:[:b | |rgb| - rgb := (((r * (boxMax+1))+g)*(boxMax+1))+b. - (bigCube at:rgb+1) ~~ 0 ifTrue:[ - (boxesSegmented includes:rgb) ifFalse:[ + rgb := (((r * (boxMaxG+1))+g)*(boxMaxB+1))+b. + (cube at:rgb+1) ~~ 0 ifTrue:[ + (boxesAlreadySegmented includes:rgb) ifFalse:[ |currentSegment| "/ start a segment @@ -3688,7 +3693,7 @@ segments add:currentSegment. boxesToDo add:rgb. - boxesSegmented add:rgb. + boxesAlreadySegmented add:rgb. [boxesToDo notEmpty] whileTrue:[ |rgb| @@ -3697,11 +3702,11 @@ currentSegment add:rgb. enumerateNeighbors value:rgb value:[:n_rgb | - (bigCube at:n_rgb+1) ~~ 0 ifTrue:[ + (cube at:n_rgb+1) ~~ 0 ifTrue:[ "/ neighbor has used pixels as well... - (boxesSegmented includes:n_rgb) ifFalse:[ + (boxesAlreadySegmented includes:n_rgb) ifFalse:[ "/ neighbor was not processed... - boxesSegmented add:rgb. + boxesAlreadySegmented add:rgb. boxesToDo add:n_rgb. ]. ]. @@ -3727,28 +3732,29 @@ eachSegment do:[:rgbOfBoxInSegment | |r g b idx count| - r := (rgbOfBoxInSegment rightShift:(numBits+numBits)) bitAnd:boxMax. - g := (rgbOfBoxInSegment rightShift:numBits) bitAnd:boxMax. - b := (rgbOfBoxInSegment) bitAnd:boxMax. - - idx := (((r * (boxMax+1))+g)*(boxMax+1))+b+1. - count := bigCube at:idx. - - sumRed := sumRed + r. - sumGreen := sumGreen + g. - sumBlue := sumBlue + b. + r := (rgbOfBoxInSegment rightShift:(numBitsG+numBitsB)) bitAnd:boxMaxR. + g := (rgbOfBoxInSegment rightShift:numBitsB) bitAnd:boxMaxG. + b := (rgbOfBoxInSegment) bitAnd:boxMaxB. + + idx := (((r * (boxMaxG+1))+g)*(boxMaxB+1))+b+1. + count := cube at:idx. + + sumRed := sumRed + (r * count). + sumGreen := sumGreen + (g * count). + sumBlue := sumBlue + (b * count). + sumWeight := sumWeight + count. ]. centerRed := (sumRed / sumWeight) rounded. centerGreen := (sumGreen / sumWeight) rounded. centerBlue := (sumBlue / sumWeight) rounded. - centerRed := (centerRed bitShift:(8-numBits)) - bitOr:(centerRed bitShift:(8-numBits-numBits)). - centerGreen := (centerGreen bitShift:(8-numBits)) - bitOr:(centerGreen bitShift:(8-numBits-numBits)). - centerBlue := (centerBlue bitShift:(8-numBits)) - bitOr:(centerBlue bitShift:(8-numBits-numBits)). + centerRed := (centerRed bitShift:(8-numBitsR)) + bitOr:(centerRed bitShift:(8-numBitsR-numBitsR)). + centerGreen := (centerGreen bitShift:(8-numBitsG)) + bitOr:(centerGreen bitShift:(8-numBitsG-numBitsG)). + centerBlue := (centerBlue bitShift:(8-numBitsB)) + bitOr:(centerBlue bitShift:(8-numBitsB-numBitsB)). Color redByte:centerRed greenByte:centerGreen blueByte:centerBlue. ] @@ -3771,10 +3777,11 @@ ^ segmentColors. ]. - numBits := numBits - 1. - boxMax := ((boxMax+1) // 2) - 1. + numBitsR > 2 ifTrue:[ numBitsR := numBitsR - 1 ]. + numBitsG > 2 ifTrue:[ numBitsG := numBitsG - 1 ]. + numBitsB > 2 ifTrue:[ numBitsB := numBitsB - 1 ]. - numBits == 0 ifTrue:[ + ((numBitsR == 0) or:[numBitsG == 0 or:[numBitsB == 0]]) ifTrue:[ self error. ]. ] loop. @@ -3795,7 +3802,7 @@ " "Created: / 29-08-2017 / 14:31:19 / cg" - "Modified: / 29-08-2017 / 20:04:36 / cg" + "Modified: / 29-08-2017 / 21:53:47 / cg" ! browserColors