Skip to content

Commit f5dcdcd

Browse files
author
therealbluepandabear
committed
Use getPixels and setPixels for Bitmap.replacePixelsByColor => massive performance increase (fix #166).
1 parent b305dd1 commit f5dcdcd

4 files changed

Lines changed: 38 additions & 13 deletions

File tree

app/src/main/java/com/therealbluepandabear/pixapencil/activities/canvas/canvascommands/CanvasActivity+CanvasCommandsHelper+replacePixelsByColor.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package com.therealbluepandabear.pixapencil.activities.canvas.canvascommands
22

33
import com.therealbluepandabear.pixapencil.activities.canvas.CanvasActivity
4-
import com.therealbluepandabear.pixapencil.extensions.getPixel
5-
import com.therealbluepandabear.pixapencil.extensions.iterate
4+
import com.therealbluepandabear.pixapencil.extensions.replacePixelsByColor
65
import com.therealbluepandabear.pixapencil.fragments.canvas.pixelGridViewInstance
76
import com.therealbluepandabear.pixapencil.models.BitmapAction
87

@@ -11,10 +10,8 @@ fun CanvasActivity.CanvasCommandsHelper.replacePixelsByColor(colorToFind: Int, c
1110

1211
baseReference.viewModel.currentBitmapAction = BitmapAction(mutableListOf())
1312

14-
pixelGridViewInstance.pixelGridViewBitmap.iterate {
15-
if (pixelGridViewInstance.pixelGridViewBitmap.getPixel(it) == colorToFind) {
16-
overrideSetPixel(it, colorToReplace, true, ignoreSymmetry = true, ignoreDither = true, ignoreShadingMap = true)
17-
}
13+
pixelGridViewInstance.pixelGridViewBitmap.replacePixelsByColor(colorToFind, colorToReplace) {
14+
overrideSetPixel(it, colorToReplace, true, ignoreSymmetry = true, ignoreDither = true, ignoreShadingMap = true)
1815
}
1916

2017
baseReference.viewModel.bitmapActionData.add(baseReference.viewModel.currentBitmapAction!!)

app/src/main/java/com/therealbluepandabear/pixapencil/extensions/BitmapExtensions.kt

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import android.graphics.Bitmap
44
import android.graphics.Canvas
55
import android.graphics.Color
66
import android.graphics.Matrix
7+
import android.util.Log
78
import com.therealbluepandabear.pixapencil.enums.OverlayType
8-
import com.therealbluepandabear.pixapencil.fragments.canvas.pixelGridViewInstance
99
import com.therealbluepandabear.pixapencil.models.Coordinates
1010
import com.therealbluepandabear.pixapencil.models.MatrixInfo
11+
import kotlin.math.ceil
12+
import kotlin.system.measureTimeMillis
1113

1214
fun Bitmap.iterate(func: (Coordinates) -> Unit) {
1315
for (i_1 in 0 until width) {
@@ -17,12 +19,30 @@ fun Bitmap.iterate(func: (Coordinates) -> Unit) {
1719
}
1820
}
1921

20-
fun Bitmap.replacePixelsByColor(colorToFind: Int, colorToReplace: Int) {
21-
iterate {
22-
if (getPixel(it) == colorToFind) {
23-
setPixel(it, colorToReplace)
22+
fun Bitmap.size(): Int {
23+
return width * height
24+
}
25+
26+
/** Thank you to to confucius on StackOverflow for this solution.
27+
*
28+
* - [Link to confucius' profile](https://stackoverflow.com/users/671676/confucius)
29+
* - [Original StackOverFlow post](https://stackoverflow.com/questions/7237915/replace-black-color-in-bitmap-with-red)
30+
* **/
31+
32+
fun Bitmap.replacePixelsByColor(colorToFind: Int, colorToReplace: Int, func: ((Coordinates) -> Unit)? = null) {
33+
val array = IntArray(size())
34+
35+
getPixels(array, 0, width, 0, 0, width, height)
36+
37+
for (i in array.indices) {
38+
if (array[i] == colorToFind) {
39+
array[i] = colorToReplace
40+
41+
func?.invoke(Coordinates.fromIndex(i, width))
2442
}
2543
}
44+
45+
setPixels(array, 0, width, 0, 0, width, height)
2646
}
2747

2848
fun Bitmap.getNumberOfUniqueColors(excludeTransparentPixels: Boolean = true): Int {

app/src/main/java/com/therealbluepandabear/pixapencil/fragments/findandreplace/FindAndReplaceFragment.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import android.graphics.Bitmap
55
import android.os.Bundle
66
import android.view.*
77
import androidx.core.view.MenuHost
8-
import androidx.core.view.MenuProvider
9-
import androidx.core.view.children
108
import androidx.fragment.app.Fragment
119
import androidx.lifecycle.Lifecycle
1210
import androidx.recyclerview.widget.LinearLayoutManager

app/src/main/java/com/therealbluepandabear/pixapencil/models/Coordinates.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.therealbluepandabear.pixapencil.models
22

3+
import kotlin.math.floor
4+
35
data class Coordinates(val x: Int, val y: Int) {
46
private fun swap(): Coordinates {
57
return Coordinates(y, x)
@@ -65,5 +67,13 @@ data class Coordinates(val x: Int, val y: Int) {
6567
fun staticSet(x: Int, y: Int): Coordinates {
6668
return Coordinates(x, y)
6769
}
70+
71+
// thanks to PapaBread for this solution ;)
72+
fun fromIndex(index: Int, bitmapWidth: Int): Coordinates {
73+
return Coordinates(
74+
x = (index.toDouble() % bitmapWidth.toDouble()).toInt(),
75+
y = floor(index.toDouble() / bitmapWidth).toInt()
76+
)
77+
}
6878
}
6979
}

0 commit comments

Comments
 (0)