Sayok Majumder
Sayok Majumder

Reputation: 1091

How to increase Opacity/Strength of Shadow in canvas android?

I am trying to get a shadow effect on a text in canvas. The problem I am facing is the shadow that is being created is very dim and showing weird shapes. I am trying to overcome these problems. I am open to suggestions where I can create Images and save to disk without using canvas.

Code:

class MainActivity : AppCompatActivity() {

    private lateinit var canvasIV: ImageView
    private lateinit var imgBitmap: Bitmap
    private lateinit var canvas: Canvas

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        canvasIV = findViewById(R.id.canvasIV)

        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        val height = displayMetrics.heightPixels
        val width = displayMetrics.widthPixels


        imgBitmap =
            Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565)
        canvas = Canvas(imgBitmap)

        canvas.drawBitmap(imgBitmap, 0f, 0f, null)

        val shadowPaint = Paint()
        shadowPaint.isAntiAlias = true
        shadowPaint.color = Color.parseColor("#F897B9")

        val tSize = 80.0f

        shadowPaint.textSize = tSize
        shadowPaint.strokeWidth = 20.0f
        shadowPaint.style = Paint.Style.FILL
        shadowPaint.alpha = 0x100
        //shadowPaint.setShadowLayer(20.0f, 5f, 5f, Color.parseColor("#F897B9"))
        shadowPaint.setShadowLayer(tSize, 5f, 5f, Color.GREEN)


        canvas.drawText("Sayok Dey Majumder", 50f, 200f, shadowPaint)
        //canvasIV.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
        canvasIV.setImageDrawable(BitmapDrawable(resources, imgBitmap))


    }
    fun convertToPixels(context: Context, nDP: Int): Float {
        val conversionScale: Float = context.getResources().getDisplayMetrics().density
        return (nDP * conversionScale + 0.5f)
    }


    fun getTextWidth(text: String, paint: Paint): Int {
        val bounds = Rect()
        paint.getTextBounds(text, 0, text.length, bounds)
        return bounds.left + bounds.width()
    }

    fun getTextHeight(text: String, paint: Paint): Int {
        val bounds = Rect()
        paint.getTextBounds(text, 0, text.length, bounds)
        return bounds.bottom + bounds.height()
    }


}

What I am getting is:

enter image description here

What I am trying to achieve:

enter image description here

Upvotes: 0

Views: 571

Answers (1)

HFZ
HFZ

Reputation: 422

The Bitmap with config Bitmap.Config.ARGB_8888 don't support Alpha channel.

Use this instead:

imgBitmap =Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)

also the following line don't do anything:

canvas.drawBitmap(imgBitmap, 0f, 0f, null)


Better Solution:

Also, shadow layer has limited capacity and I recommend to draw the shadow manually.

val shadowPaint = Paint(defaultPaint)
// ... here customize shadow paint
canvas.drawText("your text", x, y, defaultPaint);
canvas.drawText("your text", x, y, shadowPaint);

Also, you could extend TextView and override the onDraw function. Here I create customView that add shadow. you could adjust it.

import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.TextPaint;
import android.util.AttributeSet;


public class ShadowTextView extends androidx.appcompat.widget.AppCompatTextView {
    private TextPaint normalPaint;
    private int color;
    TextPaint shadowPaint;
    public ShadowTextView(Context context) {
        super(context);
        init();
    }

    public ShadowTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ShadowTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        normalPaint=new TextPaint(getPaint());
        shadowPaint=new TextPaint(getPaint());
        shadowPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        shadowPaint.setStrokeCap(Paint.Cap.ROUND);
        shadowPaint.setStrokeJoin(Paint.Join.ROUND);
        shadowPaint.setStrokeWidth(30);
        shadowPaint.setMaskFilter(new BlurMaskFilter( 10, BlurMaskFilter.Blur.NORMAL));
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        this.savePaint();
        getPaint().set(shadowPaint);
        setTextColor(Color.argb(100,255,0,0));
        super.onDraw(canvas);
        this.restorePaint();
    }


    public void savePaint() {
        normalPaint.set(getPaint());
        color=getCurrentTextColor();
    }

    public void restorePaint() {
        getPaint().set(normalPaint);
        setTextColor(color);
    }
}

enter image description here

Upvotes: 2

Related Questions