Для рисования линии толщиной менее одного пикселя требуется сглаживание в Android 4.2.

Я пытаюсь нарисовать очень тонкую линию (толщиной менее одного пикселя) в Android. я использую

Paint blackThin = new Paint();
blackThin.setStrokeWidth(0.1f);
blackThin.setColor(Color.BLACK);

для инициализации объекта рисования.

Это отлично работает в Android 2.2, но когда я пробую это в 4.2 (также 4.1, я думаю - я проверял это вкратце - я не тестировал другие версии, кроме 2.2, 4.1.2 и 4.2), строки не будут появляются, когда я их рисую. Чтобы они отображались в версии 4.2, я должен установить флаг сглаживания в значение true. (Я попробовал это, и линии появились.) Но я действительно не хочу этого, потому что это размывает линии и тому подобное.

Это баг андроида? Есть ли что-то, что я могу сделать, чтобы заставить его работать, кроме включения сглаживания?

РЕДАКТИРОВАТЬ: я также тестировал это с размером пикселя 0,9, и проблема та же.

Спасибо за помощь!


person Shdus    schedule 01.01.2013    source источник
comment
Как, по вашему мнению, будет выглядеть линия толщиной 0,1 пикселя без сглаживания?   -  person Matti Virkkunen    schedule 02.01.2013
comment
В версии 2.2 работает нормально. Просто очень тонкая грань. И кстати, 0.9 имеет ту же проблему, что и 0.1.   -  person Shdus    schedule 02.01.2013
comment
Скорее: в 2.2 работает случайно. Наименьшая вещь, которую можно нарисовать, — это один пиксель, почему вы ожидаете, что будут нарисованы объекты меньшего размера?   -  person robertc    schedule 02.01.2013


Ответы (2)


Если вам нужна очень тонкая линия, используйте setStrokeWidth(0), так как документация говорит Pass 0 to stroke in hairline mode.

Субпиксельное рисование, очевидно, требует сглаживания или других обходных путей. Вполне возможно, что, например. при программном рендеринге линии ниже одного пикселя всегда рисуются как тонкие линии, но при аппаратном рендеринге (который может автоматически использоваться в Android 4.2, но не в 2.2) поведение меняется, и многие удобные функции исчезают. (Кстати, это часто является причиной различий в рисовании и странных глюков.)

person Jan Schejbal    schedule 01.01.2013
comment
Я видел эту документацию и попробовал ее, но использование setStrokeWidth(0) дало мне те же результаты, что и при использовании setStrokeWidth(1). Должен ли я установить определенный флаг, чтобы заставить это работать? Кроме того, я использую эмулятор. Может ли это влиять? - person Shdus; 02.01.2013
comment
Я не уверен, вы всегда должны тестировать на реальном устройстве. Вы можете попробовать отключить аппаратный рендеринг (см. doc) для тестирование. Несмотря на то, что рисунок в режиме волосяного покрова не упоминается как проблема, документ может быть неполным. Кроме того, почему вы пытаетесь сделать субпиксельную линию без сглаживания вместо того, чтобы установить ее на 1 пиксель и, возможно, настроить цвет? - person Jan Schejbal; 02.01.2013
comment
К сожалению, у меня нет прямого доступа к более новому устройству. Но в этом вы правы на 100%! Я безуспешно пробовал играть с различными комбинациями настроек аппаратного ускорения. Но спасибо за идею. Что вы предлагаете? Сделать линию толщиной 1 пиксель, но использовать более светлый цвет, чтобы она выглядела меньше? - person Shdus; 02.01.2013
comment
Да, линия в 1 пиксель с более светлым цветом — это именно то, что вам нужно, если вы действительно хотите, чтобы она выглядела меньше, не включая сглаживание (тогда вы в основном выполняете сглаживание вручную). Однако учтите, что линия в 1 пиксель на устройствах xhdpi с разрешением 300+ dpi уже очень тонкая. - person Jan Schejbal; 02.01.2013

Вы не можете рисовать линии меньше пикселя в width без сглаживания.

Весь смысл сглаживания заключается в том, чтобы рассчитать, каким будет цвет пикселя, если элемент не полностью заполняет пиксель (например, линия, ширина которой составляет всего одну десятую часть пикселя).

Вы можете немного сымитировать это, нарисовав более светлую линию, но это все равно не приблизится к линии, на самом деле сглаженной.

Взгляните, например, на это изображение:

введите здесь описание изображения

На самом деле невозможно воспроизвести результат сглаживания, изменив цвет линии.

Я понимаю, что линии в примере имеют ширину > 1 пикселя, но применяется тот же принцип. «Темнота» пикселя рассчитывается в зависимости от того, какая часть пикселя заполнена линией. По этой причине сплошная серая линия не будет работать.

person Cerbrus    schedule 02.01.2013