【问题标题】:How to convert a Drawable to a scaled Bitmap如何将 Drawable 转换为缩放位图
【发布时间】:2014-10-24 17:02:26
【问题描述】:

在我的 ImageView 的onDraw 中,我正在努力将 Drawable 对象转换为位图(考虑缩放)。我正在加载一个 SVG 文件作为 PictureDrawable。然后我尝试使用 BitmapShader 将圆角应用于图像。为此,我必须将 Drawable 转换为位图。它基本上可以工作,但我对缩放过程没有了解。

Bitmap bitmap = Bitmap.createBitmap(
    picture.getIntrinsicWidth(),
    picture.getIntrinsicHeight(),
    Bitmap.Config.ARGB_8888
)

Canvas canvas = new Canvas( bitmap )
// Scaling the Canvas appears to work ...
canvas.concat( getImageMatrix() )
canvas.drawPicture(
    picture.getPicture,
    // ... however this will not fill the viewport, as the getWidth and getHeight
    // values do not reflect the scaling
    new RectF( 0, 0, canvas.getWidth(), canvas.getHeight() )
)

paint.setShader( new BitmapShader( bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP ) )
canvas.drawRoundRect(
    new RectF( 0, 0, bitmap.getWidth(), bitmap.getHeight() ),
    radius,
    radius,
    paint
)

centerCrop 缩放的错误渲染示例:

除了上面代码 cmets 中描述的问题之外,我想知道是否可以使用诸如 clipPath 之类的绘图操作来屏蔽图片/SVG 文件,而不是这种繁重的位图转换。当然,它必须是抗锯齿的。

代码最初是用 Scala 编写的,为了 SO 而松散地翻译成 Java,所以请忽略任何语法错误

【问题讨论】:

  • 关闭 hwd acc 并使用 clipPath
  • 或将 Canvas.saveLayer 与 SRC_IN porter duff 模式一起使用
  • 我找到了您的答案 (stackoverflow.com/questions/22200614/…),您的代码立即为我工作。经过几个小时的麻烦。将其发布为答案,我很乐意接受!
  • 完全正确.. 我完全忘记了那个答案... ;)

标签: android android-canvas android-imageview android-bitmap androidsvg


【解决方案1】:

根据 pskink 对类似问题的回答 (Make Image view rounded (not the image)),我基于 saveLayer 方法(稍作修改)得出了以下解决方案。

@Override
public void onDraw( Canvas canvas )
{
    Paint paint1 = new Paint( Paint.ANTI_ALIAS_FLAG )
    Paint paint2 = new Paint()
    paint2.setXfermode( new PorterDuffXfermode( Mode.SRC_IN ) )

    Drawable drawable = getDrawable()
    RectF rectangle = new RectF()
    rectangle.set( drawable.getBounds() )

    getImageMatrix.mapRect( rectangle )
    rectangle.offset( getPaddingLeft(), getPaddingTop() )

    // Prevent radius being drawn out of canvas bounds
    rectangle.intersect( new RectF( 0, 0, canvas.getWidth(), canvas.getHeight() ) )

    int restore = canvas.saveLayer( rectangle, null, Canvas.ALL_SAVE_FLAG )
    canvas.drawRoundRect( rectangle, radius.getValue(), radius.getValue(), paint1 )
    canvas.saveLayer( rectangle, paint2, Canvas.ALL_SAVE_FLAG )
    super.onDraw( canvas )
    canvas.restoreToCount( restore )
}

上面的代码忽略了类级别的对象缓存,也忽略了来自 getDrawable() 的 NPE。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-03
    • 2019-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多