1

私の ImageView ではonDraw、Drawable オブジェクトをビットマップに変換するのに苦労しています (スケーリングを考慮して)。SVG ファイルを PictureDrawable として読み込んでいます。次に、BitmapShader を使用して画像に角を丸くしようとしています。そのためには、Drawable を Bitmap に変換する必要があります。基本的には機能しますが、スケーリング手順については頭に浮かびません。

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 スケーリングの誤ったレンダリングの例: スクリーンショット

上記のコード コメントで説明されている問題に加えて、この重いビットマップ変換の代わりに、clipPath などの描画操作で画像/SVG ファイルをマスクできるかどうか疑問に思っています。しかし、もちろん、アンチエイリアスが必要です。

コードはもともと Scala で書かれており、SO 用に大まかに Java に変換されているため、構文エラーは無視してください。

4

1 に答える 1

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 を無視します。

于 2014-10-26T21:22:43.463 に答える