Сглаживание холста с аппаратным ускорением (Android API 11 и новее) - PullRequest
4 голосов
/ 16 марта 2012

У меня есть простое растровое изображение, которое я рисую внутри холста и которое я вращаю с использованием матрицы.

Проблема, с которой я сталкиваюсь, заключается в том, что при аппаратном ускорении края не сглаживаются при повороте (этоотлично работает с отключением аппаратного ускорения).И, конечно, такие вещи, как «setDrawFilter», бесполезны, поскольку они игнорируются при включении аппаратного ускорения!

canvas.setDrawFilter(new PaintFlagsDrawFilter(1, Paint.ANTI_ALIAS_FLAG));

Я что-то упустил или это просто ограничение метода аппаратного рендеринга?Есть ли альтернатива?

Ответы [ 3 ]

8 голосов
/ 16 марта 2012

Установка флага сглаживания на краске в любом случае не поможет.Чтобы получить сглаженные границы растрового изображения при их вращении, необходимо добавить прозрачную рамку размером 1 пиксель вокруг них.

1 голос
/ 29 марта 2012

Добавление этой прозрачной границы в 1px не так просто, как я думал.Добавление этого во время выполнения действительно грязно.Мое приложение загружает много растровых изображений, и чтобы добавить эту границу, мне нужно выделить еще больше растровых изображений для их перерисовки.Это действительно разрушает кучу, но, поскольку я позаботился о том, чтобы избежать утечки памяти, он работает как задумано.Что действительно убивает меня, так это «лаги», которые это принесло.Я отследил эту текучесть, потерянную для GC.Последнее, кажется, замедляет поток пользовательского интерфейса, когда он возвращает обратно переработанные растровые изображения.Использование кэша также не является решением.Это лучший способ повышения производительности, но хранение 500x500 PNG (с обязательной альфа-версией) является непропорциональным.Итак, вот я, бьюсь о стену.Я еще не пробовал способ «рисования времени», но я предполагаю, что рисование в буфере растровых изображений вне экрана, который я не думаю, будет HW в соответствии.(поправьте меня, если я ошибаюсь) не поможет моему делу.

Идея иметь «шейдер АА» действительно соблазняет, и я вижу здесь несколько преимуществ.Он хорошо поддерживается аппаратным ускорением, конечно, будет чудом для памяти (больше не будет дикого выделения растровых изображений) и может быть полностью независим от растрового масштабирования.Я сделал быстрый тест, и это лучший АА (и здесь я имею в виду по качеству), который мне когда-либо удавалось получить, и… это быстро… В этом быстром заключении можно сделать верхний край АА с использованием шейдеров.

Теперь большой недостаток!Как получить 4 ребра АА :) ???Вероятно, мы можем управлять верхним / нижним краем АА, используя многошаговый градиент, но он все еще грязный.Хорошим способом будет объединение исходного растрового изображения с каким-то 9-патчем для получения прозрачной границы, но мы не можем составить 2 bitmapShader… Итак, я снова здесь.Как получить эту маску Shader!Чертова стена;)

0 голосов
/ 21 декабря 2016

Исправление, которое работало в моем случае:

private void fixAntiAlias(View viewFromThe80s) {
    if (Build.VERSION.SDK_INT > 10) {
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
        viewFromThe80s.setLayerType(View.LAYER_TYPE_SOFTWARE, p);
        ((View) viewFromThe80s.getParent()).setLayerType(View.LAYER_TYPE_SOFTWARE, p);
    }
}

Подробности:

В моем текстовом представлении в качестве фона использовалось 9-исправление, поэтому я не мог добавить прозрачную границу 1pxбез воздействия на 9-патч пикселей.Так что вместо этого я смог заставить это работать, отключив аппаратное ускорение для данного представления и его родителя:

Я называю это сразу после инфляции представления.В частности, в onCreateViewHolder в моем случае (если быть точным, в конструкторе-держателе).Это исправляет мой повернутый TextView, который использует фон NinePatchDrawable, подобный следующему:

<TextView
    android:id="@+id/text_new_feature"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:rotation="-30"
    android:background="@drawable/background_new_feature"/>
...