2013-07-22 68 views
9

我目前通过绘制到画布中在我的应用中创建图像的圆角版本。我想在图像周围画一个淡淡的阴影,但我不能完全正确。我有两个问题: 1.如何绘制外部阴影(我似乎只能用斧子或y偏移绘制阴影) 2.如何绘制阴影以便它没有显示在工具栏中的工件附加的图像。代码:绘制图像时绘制外部阴影

![public Bitmap getRoundedCornerBitmap(Bitmap bitmap, float cornerRadius) { 
     Bitmap output = Bitmap.createBitmap(bitmap.getWidth()+6, bitmap.getHeight() +6, Config.ARGB_8888); 
     Canvas canvas = new Canvas(output); 

     final int color = 0xff424242; 
     int shadowRadius = getDipsFromPixel(3); 
     final Rect imageRect = new Rect(shadowRadius, shadowRadius, bitmap.getWidth(), bitmap.getHeight()); 
     final RectF rectF = new RectF(imageRect); 

     // This does not achieve the desired effect 
     Paint shadowPaint = new Paint(); 
     shadowPaint.setAntiAlias(true); 
     shadowPaint.setColor(Color.BLACK); 
     shadowPaint.setShadowLayer((float)shadowRadius, 2.0f, 2.0f,Color.BLACK); 
     canvas.drawOval(rectF, shadowPaint); 

     canvas.drawARGB(0, 0, 0, 0); 
     final Paint paint = new Paint(); 
     paint.setAntiAlias(true); 
     paint.setColor(color); 

     canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, paint); 

     paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
     canvas.drawBitmap(bitmap, imageRect, imageRect, paint); 

     return output; 
    }][1] 

http://i.stack.imgur.com/d7DV6.png

这是我想达到的效果的例子: enter image description here

+0

@Leonidos我现在附上了一个例子。你会发现图像周围有一个微弱的外部阴影。 – RunLoop

回答

13

在这里,我们去

http://i.imgur.com/cKi1ckX.png 是啊我还是掏了Nexus S的

首先,请停止掩盖位图唉,你可以做到这一点,而无需分配Bitmap,结帐this blog post about how to draw rounded (and actually any shape) images

使用Drawable你也许可以弄清楚如何增加你的影子,只是确保它不会削波,在18岁以上,你可以使用ViewOverlay S代表的是,也记住there are several unsupported drawing operations for hardware accelerated layers,包括二setShadowLayerBlurMaskFilter,如果性能是不是你的问题,你可以一如既往禁用它:

if (SDK_INT >= HONEYCOMB) { 
    view.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
} 

并使用setShadowLayer因为你已经尝试:

somePaint.setShadowLayer(shadowSize, deltaX, deltaY, shadowColor); 

有关示例,请查看最后的链接。

如果你仍然想硬件加速,你将不得不假冒它有透支的风险,你可以使用径向渐变或自己画一个椭圆模糊它(如前所述不能使用BlurMaskFilter)或使用pre -blurred Bitmap(更多掩饰)。

对于这样一个微妙的阴影,我宁愿只是在需要性能的情况下才变平坦,the full sauce is in the banana stand

更新:Starting L you can use real shadows

+0

嗨,谢谢你的回答和性能提示。不幸的是,我是Android新手,所以我觉得外面的阴影部分非常困难。如果你可以请张贴显示如何创建外部影子的代码(请参阅我附加到问题的图片),我会奖励你的赏金。 – RunLoop

+0

@RunLoop我已经更新了我的答案,查看底部的链接 – eveliotc

+0

非常感谢! – RunLoop

26

我想要一个类似的效果,但在AppWidget上很遗憾我不能使用@EvelioTarazona的解决方案。这是我想出的,它应该与任何形状的位图一起工作。

final Bitmap src = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); 
    final Bitmap shadow = addShadow(src, src.getHeight(), src.getWidth(), Color.BLACK, 3, 1, 3); 
    final ImageView iv = (ImageView)findViewById(R.id.image); 
    iv.setImageBitmap(shadow); 

Example with parameters size=3, dx=1, dy=3, color=BLACK

public Bitmap addShadow(final Bitmap bm, final int dstHeight, final int dstWidth, int color, int size, float dx, float dy) { 
    final Bitmap mask = Bitmap.createBitmap(dstWidth, dstHeight, Config.ALPHA_8); 

    final Matrix scaleToFit = new Matrix(); 
    final RectF src = new RectF(0, 0, bm.getWidth(), bm.getHeight()); 
    final RectF dst = new RectF(0, 0, dstWidth - dx, dstHeight - dy); 
    scaleToFit.setRectToRect(src, dst, ScaleToFit.CENTER); 

    final Matrix dropShadow = new Matrix(scaleToFit); 
    dropShadow.postTranslate(dx, dy); 

    final Canvas maskCanvas = new Canvas(mask); 
    final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    maskCanvas.drawBitmap(bm, scaleToFit, paint); 
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT)); 
    maskCanvas.drawBitmap(bm, dropShadow, paint); 

    final BlurMaskFilter filter = new BlurMaskFilter(size, Blur.NORMAL); 
    paint.reset(); 
    paint.setAntiAlias(true); 
    paint.setColor(color); 
    paint.setMaskFilter(filter); 
    paint.setFilterBitmap(true); 

    final Bitmap ret = Bitmap.createBitmap(dstWidth, dstHeight, Config.ARGB_8888); 
    final Canvas retCanvas = new Canvas(ret); 
    retCanvas.drawBitmap(mask, 0, 0, paint); 
    retCanvas.drawBitmap(bm, scaleToFit, null); 
    mask.recycle(); 
    return ret; 
} 
+1

感谢邮寄这样的答案,但阴影颜色不起作用。请建议我。 –

+1

@BalvinderSingh如果您想发布一个要点或您的问题,我很乐意提供帮助。如果您完全复制/粘贴我的代码,它应该可以正常工作... – schwiz

+1

如果我在图像上应用colorFilter,那么阴影会以我应用于图像的颜色显示,但是我想为阴影添加不同的颜色 –

2

创建它round_shape一个XML名称。XML中可绘制的文件夹

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="oval"> 

    <stroke 
     android:width="1dp" 
     android:color="#bebebe" /> 
</shape> 

设置此round_shape图像视图的作为回地面像下面

<ImageView 
    android:id="@+id/img_profile" 
    android:layout_width="120dp" 
    android:layout_height="120dp" 
    android:padding="2dp" 
    android:scaleType="fitXY" 
    android:src="@drawable/camera" /> 

上面的代码创建围绕图像视图薄层你有轮位图后,下面函数将为此

public Bitmap roundBit(Bitmap bm) { 

     Bitmap circleBitmap = Bitmap.createBitmap(bm.getWidth(), 
       bm.getHeight(), Bitmap.Config.ARGB_8888); 

     BitmapShader shader = new BitmapShader(bm, TileMode.CLAMP, 
       TileMode.CLAMP); 
     Paint paint = new Paint(); 
     paint.setShader(shader); 
     paint.setAntiAlias(true); 
     Canvas c = new Canvas(circleBitmap); 
     c.drawCircle(bm.getWidth()/2, bm.getHeight()/2, bm.getWidth()/2, 
       paint); 

     return circleBitmap; 
} 
2

enter image description here

  ImageView imageView=findViewById(R.id.iv); 
        Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.images); 
        imageView.setImageBitmap(doHighlightImage(icon)); 


      public static Bitmap doHighlightImage(Bitmap src) { 
        Bitmap bmOut = Bitmap.createBitmap(src.getWidth() + 96, src.getHeight() + 96, Bitmap.Config.ARGB_8888); 
        Canvas canvas = new Canvas(bmOut); 
        canvas.drawColor(0, Mode.CLEAR); 
        Paint ptBlur = new Paint(); 
        ptBlur.setMaskFilter(new BlurMaskFilter(15, BlurMaskFilter.Blur.NORMAL)); 
        int[] offsetXY = new int[2]; 
        Bitmap bmAlpha = src.extractAlpha(ptBlur, offsetXY); 
        Paint ptAlphaColor = new Paint(); 
        ptAlphaColor.setColor(Color.BLACK); 
        canvas.drawBitmap(bmAlpha, offsetXY[0], offsetXY[1], ptAlphaColor); 
        bmAlpha.recycle(); 
        canvas.drawBitmap(src, 0, 0, null); 
        return bmOut; 
       }