如何向矢量绘图添加阴影?

问题描述 投票:0回答:3
android vector shadow
3个回答
5
投票

所有的荣誉都归于pskink,他在评论中将此代码链接到了问题。不幸的是,这似乎仍然是唯一的解决方案

// test code
    View v = new View(this);
    setContentView(v);

    Drawable source = getResources().getDrawable(R.drawable.chrome);
    Drawable mask = getResources().getDrawable(R.drawable.chrome_mask);;
    int[] colors = {
            Color.RED, Color.BLACK
    };
    Drawable shadow = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors);
    Shape s = new S(this, source, mask, shadow, 8);
    v.setBackground(new ShapeDrawable(s));

// end of test code

~

class S extends Shape {
    Context ctx;
    Drawable source;
    Drawable mask;
    Drawable shadow;
    float shadowRadius;
    Matrix matrix = new Matrix();
    Bitmap bitmap;

    public S(Context ctx, Drawable source, Drawable mask, Drawable shadow, float shadowRadius) {
        this.ctx = ctx;
        this.source = source;
        this.mask = mask;
        this.shadow = shadow;
        this.shadowRadius = shadowRadius;
    }

    @Override
    protected void onResize(float width, float height) {
        int intrinsicWidth = source.getIntrinsicWidth();
        int intrinsicHeight = source.getIntrinsicHeight();
        source.setBounds(0, 0, intrinsicWidth, intrinsicHeight);
        mask.setBounds(0, 0, intrinsicWidth, intrinsicHeight);
        shadow.setBounds(0, 0, intrinsicWidth, intrinsicHeight);

        RectF src = new RectF(0, 0, intrinsicWidth, intrinsicHeight);
        RectF dst = new RectF(0, 0, width, height);
        matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);

        Paint p = new Paint();
        p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bitmap);

        shadow.draw(c);
        c.saveLayer(null, p, Canvas.ALL_SAVE_FLAG);
        mask.draw(c);
        c.restore();
        bitmap = blurRenderScript(bitmap);

        c = new Canvas(bitmap);
        int count = c.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
        source.draw(c);
        c.saveLayer(null, p, Canvas.ALL_SAVE_FLAG);
        mask.draw(c);
        c.restoreToCount(count);
    }

    @Override
    public void draw(Canvas canvas, Paint paint) {
        canvas.drawColor(0xffdddddd);
        canvas.drawBitmap(bitmap, matrix, null);
    }

    Bitmap blurRenderScript(Bitmap input) {
        Bitmap output = Bitmap.createBitmap(input.getWidth(), input.getHeight(), input.getConfig());
        RenderScript rs = RenderScript.create(ctx);
        ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        Allocation inAlloc = Allocation.createFromBitmap(rs, input, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
        Allocation outAlloc = Allocation.createFromBitmap(rs, output);
        script.setRadius(shadowRadius);
        script.setInput(inAlloc);
        script.forEach(outAlloc);
        outAlloc.copyTo(output);
        rs.destroy();
        return output;
    }
}

2
投票

使用上面的解决方案,我对可绘制的圆形进行了此操作:

val source: Drawable = ContextCompat.getDrawable(context,R.drawable.my_drawable)!!
val colors = intArrayOf(
                Color.GRAY, Color.TRANSPARENT
        )
val shadow: Drawable = GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, colors)
val s: Shape = DrawableShadow(context, source, source, shadow, 10f)
imageView.background = ShapeDrawable(s)
imageView.setImageResource(R.drawable.my_drawable)

和我改变的

DrawableShadow

class DrawableShadow(
    private val context: Context,
    private val source: Drawable,
    private val mask: Drawable,
    private val shadow: Drawable,
    private val shadowRadius: Float
) : Shape() {
...
override fun draw(canvas: Canvas, paint: Paint?) {
    canvas.drawColor(Color.TRANSPARENT)
...

感谢@pskink的解决方案


0
投票

如果您已经在使用 compose(或者愿意通过使用 ComposeView 和传统视图方法将其集成到您的项目中),您可以这样做:

Box{
        Icon(
            imageVector = Icons.Default.ArrowForward,
            contentDescription = null,
            Modifier
                .offset(x = (-1).dp, y = (1).dp)
                .blur(4.dp),
            tint = Color.Black
            )
            Icon(
                imageVector = Icons.Default.ArrowForward,
                contentDescription = null,
                tint = Color.White
            )
}

看起来像这样:

可以使用模糊修改器和色调参数进行调整。为了清晰起见,本示例中的图标和值进行了硬编码。

© www.soinside.com 2019 - 2024. All rights reserved.