I am creating a Unicorn Color book App and I didn't know a clue on how to do that. I found that I could use a flood fill algorithm to achieve this task. I have found this link on StackOverflow (How to use flood fill algorithm in Android?)that had led me to several other links which I have found on the code on how to Apply them in Android. but the code I have applied was slow in runtime and consume much from the memory and I have found this link for Queue-Linear Flood Fill: A Fast Flood Fill Algorithm that is created by J. Dunlap and found implementation for it on StackOverflow but I don't know hw to apply this algorithm with UI code
what I have done was creating an ImageView and applying that code for it
But I get this Exception in line 152 in QueueLinearFloodFiller class
E/InputEventReceiver: Exception dispatching input event.
E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
E/MessageQueue-JNI: java.lang.IllegalStateException
at android.graphics.Bitmap.setPixels(Bitmap.java:1804)
at com.example.unicornbookcolor.QueueLinearFloodFiller.floodFill(QueueLinearFloodFiller.java:152)
at com.example.unicornbookcolor.FastImageTry$3.onTouch(FastImageTry.java:70)
at android.view.View.dispatchTouchEvent(View.java:11931)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:527)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1875)
at android.app.Activity.dispatchTouchEvent(Activity.java:3453)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:477)
at android.view.View.dispatchPointerEvent(View.java:12183)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5510)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5260)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4802)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4761)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4910)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4769)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4967)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4802)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4761)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4769)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7494)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7468)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7425)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7612)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:159)
at android.app.ActivityThread.main(ActivityThread.java:7025)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:514)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:888)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.unicornbookcolor, PID: 3503
java.lang.IllegalStateException
at android.graphics.Bitmap.setPixels(Bitmap.java:1804)
at com.example.unicornbookcolor.QueueLinearFloodFiller.floodFill(QueueLinearFloodFiller.java:152)
at com.example.unicornbookcolor.FastImageTry$3.onTouch(FastImageTry.java:70)
at android.view.View.dispatchTouchEvent(View.java:11931)
The QueueLinearFloodFiller class:
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import java.util.LinkedList;
import java.util.Queue;
public class QueueLinearFloodFiller {
protected Bitmap image = null;
protected int[] tolerance = new int[] { 0, 0, 0 };
protected int width = 0;
protected int height = 0;
protected int[] pixels = null;
protected int fillColor = 0;
protected int[] startColor = new int[] { 0, 0, 0 };
protected boolean[] pixelsChecked;
protected Queue<FloodFillRange> ranges;
// Construct using an image and a copy will be made to fill into,
// Construct with BufferedImage and flood fill will write directly to
// provided BufferedImage
public QueueLinearFloodFiller(Bitmap img) {
copyImage(img);
}
public QueueLinearFloodFiller(Bitmap img, int targetColor, int newColor) {
useImage(img);
setFillColor(newColor);
setTargetColor(targetColor);
}
public void setTargetColor(int targetColor) {
startColor[0] = Color.red(targetColor);
startColor[1] = Color.green(targetColor);
startColor[2] = Color.blue(targetColor);
}
public int getFillColor() {
return fillColor;
}
public void setFillColor(int value) {
fillColor = value;
}
public int[] getTolerance() {
return tolerance;
}
public void setTolerance(int[] value) {
tolerance = value;
}
public void setTolerance(int value) {
tolerance = new int[] { value, value, value };
}
public Bitmap getImage() {
return image;
}
public void copyImage(Bitmap img) {
// Copy data from provided Image to a BufferedImage to write flood fill
// to, use getImage to retrieve
// cache data in member variables to decrease overhead of property calls
width = img.getWidth();
height = img.getHeight();
image = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(image);
canvas.drawBitmap(img, 0, 0, null);
pixels = new int[width * height];
image.getPixels(pixels, 0, width, 1, 1, width - 1, height - 1);
}
public void useImage(Bitmap img) {
// Use a pre-existing provided BufferedImage and write directly to it
// cache data in member variables to decrease overhead of property calls
width = img.getWidth();
height = img.getHeight();
image = img;
pixels = new int[width * height];
image.getPixels(pixels, 0, width, 1, 1, width - 1, height - 1);
}
protected void prepare() {
// Called before starting flood-fill
pixelsChecked = new boolean[pixels.length];
ranges = new LinkedList<FloodFillRange>();
}
// Fills the specified point on the bitmap with the currently selected fill
// color.
// int x, int y: The starting coords for the fill
public void floodFill(int x, int y) {
// Setup
prepare();
if (startColor[0] == 0) {
// ***Get starting color.
int startPixel = pixels[(width * y) + x];
startColor[0] = (startPixel >> 16) & 0xff;
startColor[1] = (startPixel >> 8) & 0xff;
startColor[2] = startPixel & 0xff;
}
// ***Do first call to floodfill.
LinearFill(x, y);
// ***Call floodfill routine while floodfill ranges still exist on the
// queue
FloodFillRange range;
while (ranges.size() > 0) {
// **Get Next Range Off the Queue
range = ranges.remove();
// **Check Above and Below Each Pixel in the Floodfill Range
int downPxIdx = (width * (range.Y + 1)) + range.startX;
int upPxIdx = (width * (range.Y - 1)) + range.startX;
int upY = range.Y - 1;// so we can pass the y coord by ref
int downY = range.Y + 1;
for (int i = range.startX; i <= range.endX; i++) {
// *Start Fill Upwards
// if we're not above the top of the bitmap and the pixel above
// this one is within the color tolerance
if (range.Y > 0 && (!pixelsChecked[upPxIdx])
&& CheckPixel(upPxIdx))
LinearFill(i, upY);
// *Start Fill Downwards
// if we're not below the bottom of the bitmap and the pixel
// below this one is within the color tolerance
if (range.Y < (height - 1) && (!pixelsChecked[downPxIdx])
&& CheckPixel(downPxIdx))
LinearFill(i, downY);
downPxIdx++;
upPxIdx++;
}
}
image.setPixels(pixels, 0, width, 1, 1, width - 1, height - 1);
}
// Finds the furthermost left and right boundaries of the fill area
// on a given y coordinate, starting from a given x coordinate, filling as
// it goes.
// Adds the resulting horizontal range to the queue of floodfill ranges,
// to be processed in the main loop.
// int x, int y: The starting coords
protected void LinearFill(int x, int y) {
// ***Find Left Edge of Color Area
int lFillLoc = x; // the location to check/fill on the left
int pxIdx = (width * y) + x;
while (true) {
// **fill with the color
pixels[pxIdx] = fillColor;
// **indicate that this pixel has already been checked and filled
pixelsChecked[pxIdx] = true;
// **de-increment
lFillLoc--; // de-increment counter
pxIdx--; // de-increment pixel index
// **exit loop if we're at edge of bitmap or color area
if (lFillLoc < 0 || (pixelsChecked[pxIdx]) || !CheckPixel(pxIdx)) {
break;
}
}
lFillLoc++;
// ***Find Right Edge of Color Area
int rFillLoc = x; // the location to check/fill on the left
pxIdx = (width * y) + x;
while (true) {
// **fill with the color
pixels[pxIdx] = fillColor;
// **indicate that this pixel has already been checked and filled
pixelsChecked[pxIdx] = true;
// **increment
rFillLoc++; // increment counter
pxIdx++; // increment pixel index
// **exit loop if we're at edge of bitmap or color area
if (rFillLoc >= width || pixelsChecked[pxIdx] || !CheckPixel(pxIdx)) {
break;
}
}
rFillLoc--;
// add range to queue
FloodFillRange r = new FloodFillRange(lFillLoc, rFillLoc, y);
ranges.offer(r);
}
// Sees if a pixel is within the color tolerance range.
protected boolean CheckPixel(int px) {
int red = (pixels[px] >>> 16) & 0xff;
int green = (pixels[px] >>> 8) & 0xff;
int blue = pixels[px] & 0xff;
return (red >= (startColor[0] - tolerance[0])
&& red <= (startColor[0] + tolerance[0])
&& green >= (startColor[1] - tolerance[1])
&& green <= (startColor[1] + tolerance[1])
&& blue >= (startColor[2] - tolerance[2]) && blue <= (startColor[2] + tolerance[2]));
}
// Represents a linear range to be filled and branched from.
protected class FloodFillRange {
public int startX;
public int endX;
public int Y;
public FloodFillRange(int startX, int endX, int y) {
this.startX = startX;
this.endX = endX;
this.Y = y;
}
}
}
My Activity for coloring:
public class FastImageTry extends AppCompatActivity {
private ImageView unicornImage;
private RelativeLayout dashBoard;
private ImageView imageView;
private Bitmap bitmap;
private ImageView redColor, blueColor, greenColor, blackColor,purpleColor;
private int choosedColor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fast_image_try);
//unicornImage = findViewById(R.id.unicorn_image_fast);
dashBoard = findViewById(R.id.image_view);
imageView = (ImageView)findViewById(R.id.unicorn_image_fast);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.unicorn_1);
redColor = findViewById(R.id.color_red);
redColor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
choosedColor = Color.RED;
}
});
blueColor = findViewById(R.id.color_blue);
blueColor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
choosedColor = Color.BLUE;
}
});
imageView.setOnTouchListener(new ImageView.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
int x = (int)event.getX();
int y = (int)event.getY();
final int sourceColor = bitmap.getPixel((int) x, (int) y);
QueueLinearFloodFiller queueLinearFloodFiller = new QueueLinearFloodFiller(bitmap, sourceColor, choosedColor);
queueLinearFloodFiller.floodFill(x,y);
return true;
}
});
}
I want to know what is this error means and how can i fix it and apply the coloring feature to an Images I get from Drawable. If Someone can show me an example for how to apply this algorithm with UI code so that the choosed color can fill the white space in the Image.
I have also tried to apply this method but run into an exception as will
private void FloodFill(Bitmap bmp, Point pt, int targetColor, int replacementColor){
Queue<Point> q = new LinkedList<Point>();
q.add(pt);
while (q.size() > 0) {
Point n = q.poll();
if (bmp.getPixel(n.x, n.y) != targetColor)
continue;
Point w = n, e = new Point(n.x + 1, n.y);
while ((w.x > 0) && (bmp.getPixel(w.x, w.y) == targetColor)) {
bmp.setPixel(w.x, w.y, replacementColor);
if ((w.y > 0) && (bmp.getPixel(w.x, w.y - 1) == targetColor))
q.add(new Point(w.x, w.y - 1));
if ((w.y < bmp.getHeight() - 1)
&& (bmp.getPixel(w.x, w.y + 1) == targetColor))
q.add(new Point(w.x, w.y + 1));
w.x--;
}
while ((e.x < bmp.getWidth() - 1)
&& (bmp.getPixel(e.x, e.y) == targetColor)) {
bmp.setPixel(e.x, e.y, replacementColor);
if ((e.y > 0) && (bmp.getPixel(e.x, e.y - 1) == targetColor))
q.add(new Point(e.x, e.y - 1));
if ((e.y < bmp.getHeight() - 1)
&& (bmp.getPixel(e.x, e.y + 1) == targetColor))
q.add(new Point(e.x, e.y + 1));
e.x++;
}
}}
This Error:
E/InputEventReceiver: Exception dispatching input event.
E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
E/MessageQueue-JNI: java.lang.IllegalStateException
at android.graphics.Bitmap.setPixel(Bitmap.java:1771)
at com.example.unicornbookcolor.FastImageTry.FloodFill(FastImageTry.java:86)
at com.example.unicornbookcolor.FastImageTry.access$200(FastImageTry.java:20)
at com.example.unicornbookcolor.FastImageTry$3.onTouch(FastImageTry.java:69)
at android.view.View.dispatchTouchEvent(View.java:11931)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:527)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1875)
at android.app.Activity.dispatchTouchEvent(Activity.java:3453)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:477)
at android.view.View.dispatchPointerEvent(View.java:12183)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5510)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5260)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4802)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4761)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4910)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4769)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4967)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4802)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4761)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4769)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7494)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7468)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7425)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7612)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:159)
at android.app.ActivityThread.main(ActivityThread.java:7025)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:514)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:888)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.unicornbookcolor, PID: 2420
java.lang.IllegalStateException
at android.graphics.Bitmap.setPixel(Bitmap.java:1771)
at com.example.unicornbookcolor.FastImageTry.FloodFill(FastImageTry.java:86)
at com.example.unicornbookcolor.FastImageTry.access$200(FastImageTry.java:20)
at com.example.unicornbookcolor.FastImageTry$3.onTouch(FastImageTry.java:69)
at android.view.View.dispatchTouchEvent(View.java:11931)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:527)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1875)
at android.app.Activity.dispatchTouchEvent(Activity.java:3453)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:477)
at android.view.View.dispatchPointerEvent(View.java:12183)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5510)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5260)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4802)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4761)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4910)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4769)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4967)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4802)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4761)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4769)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7494)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7468)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7425)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7612)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:159)
at android.app.ActivityThread.main(ActivityThread.java:7025)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:514)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:888)
at this line in :
bmp.setPixel(w.x, w.y, replacementColor);
How can I apply any of the tow Algorithms to my App with UI