Как преобразовать Drawable в масштабированное растровое изображение

В моем 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: screenshot

Помимо проблемы, описанной в комментариях к коду выше, мне интересно, можно ли замаскировать файл Picture/SVG с помощью операций рисования, таких как clipPath, вместо этого тяжелого преобразования Bitmap. Но это должно быть сглажено, конечно.

Код изначально был написан на Scala и частично переведен на Java для SO, поэтому не обращайте внимания на любые синтаксические ошибки


person Taig    schedule 24.10.2014    source источник
comment
отключить hwd acc и использовать clipPath   -  person pskink    schedule 24.10.2014
comment
или используйте Canvas.saveLayer с режимом duff портера SRC_IN   -  person pskink    schedule 24.10.2014
comment
Я нашел ваш ответ (stackoverflow. com/questions/22200614/), и ваш код сразу у меня работает. После нескольких часов хлопот. Опубликуйте это как ответ, и я с радостью приму его!   -  person Taig    schedule 24.10.2014
comment
точно .. я совсем забыл об этом ответе ... ;)   -  person pskink    schedule 24.10.2014


Ответы (1)


С ответом pskink (Сделать вид изображения закругленным (не изображение)) на аналогичный вопрос я пришел к следующему решению, основанному на подходе 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 )
}

Приведенный выше код игнорирует кэширование объектов на уровне класса и игнорирует NPE из getDrawable().

person Taig    schedule 26.10.2014