0

I am working on a paint tool for android and have attempted to implement a 'fill with color' tool. Where a user is able to fill a particular area with color depending on what they have selected. I have found examples of Flood Fill for Java but cant see anything similar for Kotlin.

I have tried the following - https://developer.android.com/reference/kotlin/android/graphics/Path.FillType

But have not had too much luck since it instead uses the surrounding colour and not what colour the user has selected.

EDIT:

A snippet of the code I am working with:

class DrawingView(context: Context, attrs: AttributeSet) : View(context, attrs) {

    private var mDrawPath: CustomPath? = null
    private var mCanvasBitMap: Bitmap? = null
    private var mDrawPaint: Paint? = null
    private var mCanvasPaint: Paint? = null
    private var mBrushSize: Float = 0.toFloat()
    private var color = Color.BLACK
    private var canvas: Canvas? = null
    private val mPaths = ArrayList<CustomPath>()
    private val mUndoPaths = ArrayList<CustomPath>()
    private val mRedoPaths = ArrayList<CustomPath>()
    private var counterUndo = 0


    init {
        setUpDrawing()
    }


    private fun setUpDrawing() {
        mDrawPaint = Paint()
        mDrawPath = CustomPath(color, mBrushSize)
        mDrawPaint!!.color = color
        mDrawPaint!!.style = Paint.Style.STROKE
        mDrawPaint!!.strokeJoin = Paint.Join.ROUND
        mDrawPaint!!.strokeCap = Paint.Cap.ROUND
        mCanvasPaint = Paint(Paint.DITHER_FLAG)

    }

    //Change Canvas to Canvas? if fails
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawBitmap(mCanvasBitMap!!, 0f,0f, mCanvasPaint)

        for(path in mPaths){
            mDrawPaint!!.strokeWidth = path.brushThickness
            mDrawPaint!!.color = path.color
            canvas.drawPath(path, mDrawPaint!!)
        }

        if(!mDrawPath!!.isEmpty) {
            mDrawPaint!!.strokeWidth = mDrawPath!!.brushThickness
            mDrawPaint!!.color = mDrawPath!!.color
            canvas.drawPath(mDrawPath!!, mDrawPaint!!)
        }
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        val touchX = event?.x
        val touchY = event?.y

        when(event?.action){
            MotionEvent.ACTION_DOWN -> {
                mDrawPath!!.color = color
                mDrawPath!!.brushThickness = mBrushSize

                mDrawPath!!.reset()
                mDrawPath!!.moveTo(touchX!!, touchY!!)
            }
            MotionEvent.ACTION_MOVE -> {
                mDrawPath!!.lineTo(touchX!!, touchY!!)
            }
            MotionEvent.ACTION_UP -> {
                mPaths.add(mDrawPath!!)
                mDrawPath = CustomPath(color, mBrushSize)
            }
            else -> return false
        }
        invalidate()
        return true
    }


    fun setFill(){
        mDrawPaint!!.style = Paint.Style.FILL
    }

}
    
Zomb991
  • 33
  • 4

1 Answers1

1

This is kind of a complicated subject - if you want to draw a Path with a particular fill and colour, you need to create a Paint and use setColor (and setStyle to make it Paint.Style.FILL.

But Paths are for vector graphics, they're all defined lines and curves. Unless you're creating the shapes that the user can fill in as paths in the first place, you'll have trouble defining one to fit an arbitrary area.

I'm guessing you're actually using bitmaps, like a normal paint program, and you want to tap on a pixel and have that change colour, and also recursively change the colour of surrounding pixels if they meet a certain threshold. So you'll have to get the Canvas's Bitmap, and work out how to move through the pixels, changing them as you go (e.g. with Bitmap.setPixel())

There are a lot of algorithms for doing this, you'll just need to pick one and implement it. You probably don't want to use Paths to do it though!

cactustictacs
  • 17,935
  • 2
  • 14
  • 25
  • thanks for the reply @cactustictacs ! I have just added the code i am working on for a bit of context. Do you have any examples of the algorithms mentioned? I am unsure if I might be searching for the wrong terms, but i havent found anything of use yet :/ – Zomb991 Sep 20 '20 at 04:45
  • 1
    Just search for "flood fill algorithm", it's kind of a general computer programming problem. There's a general explanation here (https://graphics.fandom.com/wiki/Flood_fill) and some Android examples around (like here: https://stackoverflow.com/questions/16968412/how-to-use-flood-fill-algorithm-in-android). You'll need to learn how to get a ``Canvas``'s ``Bitmap``, how to use ``getPixel`` and ``setPixel``, and how to implement the flood algorithm so you can move out from one pixel to its neighbours, and then to *their* neighbours and so on. I don't have any drop-in code though, sorry! – cactustictacs Sep 20 '20 at 22:59
  • also btw, you should probably just say ``private var mDrawPaint: Paint = Paint()``, you're initialising it immediately anyway and making something nullable when it's never gonna be null just causes headaches. Then you can get rid of all the ``!!`` which is usually a bad sign – cactustictacs Sep 20 '20 at 23:07