Skip to content

Commit 963aeef

Browse files
Merge pull request #47 from gdg-berlin-android/add/yubico
Add Yubico as a sponsor
2 parents e492f64 + 2c48e80 commit 963aeef

15 files changed

Lines changed: 70 additions & 53 deletions

File tree

app/src/main/java/de/berlindroid/zepatch/MainActivity.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ private fun PatchableList(
163163
onClick = { onItemClicked(name) },
164164
) {
165165
Column(
166-
modifier = Modifier.padding(8.dp),
166+
modifier = Modifier.padding(8.dp)
167167
) {
168168
Row(
169169
modifier = Modifier.fillMaxWidth(),
@@ -176,7 +176,12 @@ private fun PatchableList(
176176
)
177177
}
178178
Box(Modifier.height(4.dp))
179-
PatchableBoundingBox(patchable = patchable)
179+
Row(
180+
modifier = Modifier.fillMaxWidth(),
181+
horizontalArrangement = Arrangement.Center
182+
) {
183+
PatchableBoundingBox(patchable = patchable)
184+
}
180185
}
181186
}
182187
}

app/src/main/java/de/berlindroid/zepatch/patchable/Demo.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,26 @@ fun GoogleLogo(
9494
}
9595

9696

97+
@OptIn(ExperimentalMaterial3Api::class)
98+
@Patch("YubicoLogo")
99+
@Composable
100+
fun YubicoLogo(
101+
shouldCapture: Boolean = false,
102+
onBitmap: (ImageBitmap) -> Unit = {},
103+
) {
104+
SafeArea(
105+
shouldCapture = shouldCapture,
106+
onBitmap = onBitmap,
107+
) {
108+
Image(
109+
modifier = Modifier.size(200.dp),
110+
painter = painterResource(R.drawable.yubico),
111+
contentDescription = null
112+
)
113+
}
114+
}
115+
116+
97117
@OptIn(ExperimentalMaterial3Api::class)
98118
@Patch("Android")
99119
@Composable

app/src/main/java/de/berlindroid/zepatch/ui/PatchableToReducedBitmap.kt

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,14 @@ fun PatchableToReducedBitmap(
9090
supportingText = {
9191
if (!isValidColorCount(colorText)) {
9292
Text(
93-
text = "Please enter a valid number (3 or more)",
93+
text = "Please enter a valid color count (between 1 and 7)",
9494
color = androidx.compose.material3.MaterialTheme.colorScheme.error
9595
)
9696
}
9797
}
9898
)
9999

100-
Button(enabled = isValidColorCount(colorText) , onClick = computeReducedBitmap) { Text("Reduce") }
100+
Button(enabled = isValidColorCount(colorText), onClick = computeReducedBitmap) { Text("Reduce") }
101101

102102
reducedImage?.let {
103103
Image(
@@ -109,14 +109,8 @@ fun PatchableToReducedBitmap(
109109
}
110110
}
111111

112-
fun isValidColorCount(colorCountText: String): Boolean =
113-
when {
114-
colorCountText.isEmpty() -> false
115-
colorCountText.toIntOrNull() == null -> false
116-
colorCountText.toInt() < 3 -> false
117-
else -> true
118-
}
119-
112+
fun isValidColorCount(colorCountText: String): Boolean =
113+
(colorCountText.toIntOrNull() ?: -1) in 1..7
120114

121115

122116
@Preview(showBackground = true)

app/src/main/java/de/berlindroid/zepatch/utils/Text.kt

Lines changed: 0 additions & 8 deletions
This file was deleted.
1.79 KB
Loading
-520 Bytes
Binary file not shown.

app/src/main/res/drawable/g.png

85.9 KB
Loading

app/src/main/res/drawable/g.webp

-892 Bytes
Binary file not shown.
63.3 KB
Loading

converter/src/main/java/de/berlindroid/zepatch/stiches/ImageManipulation.kt

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,9 @@ data class Histogram(
1717
val spread: Map<Color, Amount>
1818
)
1919

20-
val Histogram.colors : Set<Color>
20+
val Histogram.colors: Set<Color>
2121
get() = spread.keys
2222

23-
fun Histogram.hasAlpha(): Boolean = colors.firstOrNull {
24-
it.alpha < 0xff
25-
} != null
26-
2723
fun Bitmap.colorHistogram(): Histogram {
2824
// all colors
2925
val result = mutableMapOf<Color, Amount>()
@@ -45,21 +41,29 @@ fun Bitmap.colorHistogram(): Histogram {
4541
}
4642

4743
fun Bitmap.reduceColors(maxColorCounts: Int): Pair<Bitmap, Histogram> {
48-
var histogram = colorHistogram().mergeSimilarColors().removeLowCounts()
49-
val hasAlpha = histogram.hasAlpha()
50-
val desiredColorCount = (if (hasAlpha) 1 else 0) + maxColorCounts
44+
val minDistance = 25
45+
var histogram =
46+
colorHistogram()
47+
.mergeSimilarColors(maxColorCounts, minDistance)
48+
.removeLowCounts(maxColorCounts, minDistance)
5149

5250
var maxTries = 3
53-
while (histogram.colors.size > desiredColorCount && maxTries > 0) {
54-
histogram = histogram.mergeSimilarColors().removeLowCounts()
51+
while (histogram.colors.size > maxColorCounts && maxTries > 0) {
52+
histogram = histogram
53+
.mergeSimilarColors(maxColorCounts, minDistance)
54+
.removeLowCounts(maxColorCounts, minDistance)
5555
maxTries--
5656
}
5757

5858
maxTries = 3
5959
var currentDistance = 50
60+
6061
// reduce more aggressively
61-
while (histogram.colors.size > desiredColorCount && maxTries > 0) {
62-
histogram = histogram.mergeSimilarColors(currentDistance).removeLowCounts()
62+
while (histogram.colors.size > maxColorCounts && maxTries > 0) {
63+
histogram = histogram
64+
.mergeSimilarColors(maxColorCounts, currentDistance)
65+
.removeLowCounts(maxColorCounts, currentDistance)
66+
6367
currentDistance = (currentDistance * 1.25f).toInt()
6468
maxTries--
6569
} // todo if not reject and give up
@@ -69,7 +73,7 @@ fun Bitmap.reduceColors(maxColorCounts: Int): Pair<Bitmap, Histogram> {
6973
.spread
7074
.toList()
7175
.sortedByDescending { it.second }
72-
.take(desiredColorCount)
76+
.take(maxColorCounts)
7377
.toMap()
7478
)
7579

@@ -86,7 +90,11 @@ fun Bitmap.reduceColors(maxColorCounts: Int): Pair<Bitmap, Histogram> {
8690
return result to histogram
8791
}
8892

89-
fun Histogram.mergeSimilarColors(distance: Int = 25): Histogram {
93+
fun Histogram.mergeSimilarColors(maxColorCounts: Int, distance: Int): Histogram {
94+
if (spread.size <= maxColorCounts) {
95+
return this
96+
}
97+
9098
val result = mutableMapOf<Color, Amount>()
9199

92100
for (e in spread) {
@@ -109,7 +117,11 @@ fun Histogram.mergeSimilarColors(distance: Int = 25): Histogram {
109117
return Histogram(result)
110118
}
111119

112-
fun Histogram.removeLowCounts(threshold: Int = 25): Histogram {
120+
fun Histogram.removeLowCounts(maxColorCounts: Int, threshold: Int): Histogram {
121+
if (spread.size <= maxColorCounts) {
122+
return this
123+
}
124+
113125
val result = mutableMapOf<Color, Amount>()
114126
var removedCount = 0
115127

@@ -143,27 +155,21 @@ private fun IntArray.filteredBy(targetPixels: List<Int>): IntArray {
143155
}
144156

145157
private fun distance(a: Int, b: Int): Float {
146-
val aA = a.alpha
158+
val aR = a.red
159+
val aG = a.green
160+
val aB = a.blue
147161

148-
return if (aA < 0xff) {
149-
0f
150-
} else {
151-
val aR = a.red
152-
val aG = a.green
153-
val aB = a.blue
162+
val aLAB = DoubleArray(3)
163+
RGBToLAB(aR, aG, aB, aLAB)
154164

155-
val aLAB = DoubleArray(3)
156-
RGBToLAB(aR, aG, aB, aLAB)
165+
val bR = b.red
166+
val bG = b.green
167+
val bB = b.blue
157168

158-
val bR = b.red
159-
val bG = b.green
160-
val bB = b.blue
169+
val bLAB = DoubleArray(3)
170+
RGBToLAB(bR, bG, bB, bLAB)
161171

162-
val bLAB = DoubleArray(3)
163-
RGBToLAB(bR, bG, bB, bLAB)
164-
165-
ColorUtils.distanceEuclidean(aLAB, bLAB).toFloat()
166-
}
172+
return ColorUtils.distanceEuclidean(aLAB, bLAB).toFloat()
167173
}
168174

169175

0 commit comments

Comments
 (0)