如何在canvasandroid中增加Opacity/Strength的影子?

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

我正在尝试对 canvas 中的文本产生阴影效果。我面临的问题是正在创建的阴影非常暗淡并且显示出奇怪的形状。我正在努力克服这些问题。我愿意接受可以在不使用 canvas.

的情况下创建图像并保存到磁盘的建议

代码:

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()
    }


}

我得到的是:

我想要达到的目标:

配置Bitmap.Config.ARGB_8888的位图不支持Alpha通道。

改用这个:

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

下面这行也什么都不做:

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


更好的解决方案:

另外,阴影图层容量有限,建议手动绘制阴影

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

此外,您可以扩展 TextView 并覆盖 onDraw 函数。在这里,我创建了添加阴影的 customView。你可以调整一下。

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);
    }
}