2

I'm trying to add shadow effect do an image. I use a mask to draw the image (I need a specific shape for my image). Can you please tell me how to add shadow effect to my image? I've tried something like paint.setShadowLayer(10, 10, 10, Color.RED) but it didn't worked. Here is the source code:

 @Override
public void draw(Canvas canvas) {
    Rect rect = new Rect(0, 0, getWidth() - 1, getHeight() - 1);
    NinePatchDrawable mask = (NinePatchDrawable) getContext().getResources().getDrawable(maskResId);
    mask.setBounds(rect);
    Bitmap content = Bitmap.createBitmap(rect.width(), rect.height(), Bitmap.Config.ARGB_8888);
    Canvas contentCanvas = new Canvas(content);
    super.draw(contentCanvas);
    Paint paint = new Paint();
    paint.setXfermode(new AvoidXfermode(Color.BLACK, 255, AvoidXfermode.Mode.TARGET));
    mask.draw(canvas);
    canvas.drawBitmap(content, null, rect, paint);
}
Buda Gavril
  • 21,409
  • 40
  • 127
  • 196
  • Check [CoverFlow](http://www.inter-fuser.com/2010/01/android-coverflow-widget.html) Widget. Or [Android 3D Carousel](http://www.codeproject.com/KB/android/androcarousel.aspx) You will definately get something there. – Kartik Domadiya Mar 18 '11 at 13:18
  • take a look at this answer http://stackoverflow.com/a/33889791/4356754 – Mohamed Ali Nov 24 '15 at 09:30

1 Answers1

2

my solution:

class ShadowImage

public class ShadowImage extends BitmapDrawable {

Bitmap bm;
static float shadowRadius = 4f;
static PointF shadowDirection = new PointF(2f, 2f);
int fillColor = 0;

@Override
public void draw(Canvas canvas) {

    Rect rect = new Rect(0, 0, bm.getWidth(), bm.getHeight());
    Log.i("TEST", rect.toString());
    setBounds(rect);

    Paint mShadow = new Paint();
    mShadow.setAntiAlias(true);
    mShadow.setShadowLayer(shadowRadius, shadowDirection.x, shadowDirection.y, Color.BLACK);

    canvas.drawRect(rect, mShadow);
    if(fillColor != 0) {
        Paint mFill = new Paint();
        mFill.setColor(fillColor);
        canvas.drawRect(rect, mFill);
    }
    canvas.drawBitmap(bm, 0.0f, 0.0f, null);

}

public ShadowImage(Resources res, Bitmap bitmap) {
    super(res, Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth()+shadowRadius*shadowDirection.x), (int) (bitmap.getHeight()+shadowRadius*shadowDirection.y), false));
    this.bm = bitmap;
}
public ShadowImage(Resources res, Bitmap bitmap, int fillColor) {
    super(res, Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth()+shadowRadius*shadowDirection.x), (int) (bitmap.getHeight()+shadowRadius*shadowDirection.y), false));
    this.bm = bitmap;
    this.fillColor = fillColor;
}

}

Activity:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    LinearLayout root = (LinearLayout) findViewById(R.id.root_layout);

    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
    ShadowImage image = new ShadowImage(getResources(), bmp);
    ShadowImage image2 = new ShadowImage(getResources(), bmp, Color.WHITE);

    ImageView iv_normal = new ImageView(getApplicationContext());
    iv_normal.setPadding(10, 10, 10, 10);
    iv_normal.setImageBitmap(bmp);

    ImageView iv_shadow = new ImageView(getApplicationContext());
    iv_shadow.setPadding(10, 10, 10, 10);
    iv_shadow.setImageDrawable(image);

    ImageView iv_fill = new ImageView(getApplicationContext());
    iv_fill.setPadding(10, 10, 10, 10);
    iv_fill.setImageDrawable(image2);

    LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    root.addView(iv_normal, params);
    root.addView(iv_shadow, params);
    root.addView(iv_fill, params);
    root.setGravity(Gravity.CENTER);
}

Image: Screenshot

Mario
  • 758
  • 12
  • 25
  • to state the obvious, this will only work for rect shaped images? as opposed to, for example, a png of a circle? – user3453281 Apr 14 '15 at 14:28
  • yes. this work just with rects. but you change this code to draw cycles or rounded rect with the shadow layer ATTENTION: for better performance move new XYZ() calls from draw() to init() – Mario May 28 '15 at 10:18