Cannot integrate flood fill

27 views Asked by At

In my app , I've been created my custom view, which have onTouchListener in my fragment

I have a different colors to paint with. I have two recyclerView(first containing palette list , each pallete has it own name and list of colors, the second one displaying chosen pallete on fragment).

In my app logic needs to work like this:

when user clicking palleteButton , user saws AlertDialog with list of pallettes, when user clicked any of them , alertDialog is closing and listOfColors go to second list , which will be VISIBLE(when user don't pick pallete, second list is invisible) and displayed colors it's a imageViews , which don't have src , they painted with some color.

When user click click any of color button, and touch some space in ImageView(mainImage),

this space needs to be fill with this color.

Everything working correctly, but , when user choosed color and try to fill space , which he already touch , nothing happens.

In debug I checked:

Checked if image is clicked(working correct);

color is chosen correctly.

Usually, saw that my bitmap , which I'm getting is empty or nullable.


//this is how my algo looks like:


    fun floodFill(view: View, point: Point, targetColor: Int, selectedColor: Int) {
        val width = view.width
        val height = view.height
        val bitmap = getImageBitmap(view)

        if (targetColor != selectedColor) {

            val queue: Queue<Point> = LinkedList()
            queue.add(point)

            while (queue.isNotEmpty()) {
                val currentPoint = queue.poll()
                val x = currentPoint!!.x
                val y = currentPoint.y

                if (x < 0 || x >= width || y < 0 || y >= height) {
                    continue
                }

                val pixelColor = bitmap.getPixel(x, y)

                if (pixelColor != targetColor) {
                    continue
                }

                bitmap.setPixel(x, y, selectedColor)

                queue.add(Point(x + 1, y))
                queue.add(Point(x - 1, y))
                queue.add(Point(x, y + 1))
                queue.add(Point(x, y - 1))
            }

        }
    }

   private fun getImageBitmap(view: View): Bitmap {
        val mainImageBitmap = Bitmap.createBitmap(view.width,view.height,Bitmap.Config.ARGB_8888)
        val canvas = Canvas(mainImageBitmap)
        view.draw(canvas)
        return mainImageBitmap
    }


----------
private val floodFill: FloodFill? = null // class in which contains this algo
 private var alreadyChosenColorsAdapter: AlreadyChosenColorsAdapter? = null // recyclerView Adapter
 
 
// This is my flood fill logic with view
// also want to notice , that val paintView = binding?.mainImage it's customView id in fragment layout

alreadyChosenColorsAdapter?.setOnColorClickListener(object :
    AlreadyChosenColorsAdapter.OnColorClickListener {
    override fun onColorClick(color: Int) {
        val paintView = binding?.mainImage
        binding?.mainImage?.setOnTouchListener { _, event ->
            val imageBitmap = getImageBitmap(paintView!!)
            val targetColor = imageBitmap.getPixel(
                event.x.toInt(),
                event.y.toInt()
            )

            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    floodFill?.floodFill(
                        paintView, Point(event.x.roundToInt(), event.y.roundToInt()),
                        targetColor, color
                    )
                    paintView.invalidate()
                    Log.d("TAG", "Action_down")
                }
                MotionEvent.ACTION_UP -> {
                    floodFill?.floodFill(
                        paintView, Point(event.x.roundToInt(), event.y.roundToInt()),
                        targetColor, color
                    )
                    paintView.invalidate()
                    Log.d("TAG", "Action_up")
                }
            }
            true
        }
    }
})

This code is from my recyclerViewAdapter in which I display colors pallete and Integrate on click logic:

inner class ColorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    private val colorImageView: ImageView = itemView.findViewById(R.id.color)
    private var color: Int = 0

    fun bindColor(color: Int) {
        this.color = color
        colorImageView.setImageResource(color)
        colorImageView.setOnClickListener {
            onColorClickListener?.onColorClick(this.color)
        }
    }
}


interface OnColorClickListener {
        fun onColorClick(color: Int)
    }

class PaintViewFirst(context: Context, attrs: AttributeSet?) : View(context, attrs) {
    private var bitmap: Bitmap? = null

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        val pictureSelected = R.mipmap.secondimagetopaint
        val options = BitmapFactory.Options()
        options.inSampleSize = 3

        val srcBitmap = BitmapFactory.decodeResource(resources, pictureSelected, options)
        bitmap = Bitmap.createScaledBitmap(srcBitmap, width, height, false)
        invalidate()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
            bitmap?.let {
                canvas.drawBitmap(it, 0f, 0f, null)
            }
    }
} // this is customView initialization class.
0

There are 0 answers