Есть ли техническая причина, по которой drawImage() холста не выполняет субпиксельный рендеринг/сглаживание?

Ttl;dr: Мне нужно ОЧЕНЬ медленно перемещать изображение в canvas без явного попиксельного движения. Мне нужно какое-то сглаживание.


Недавно мне поручили анимировать некоторые «облачные» рисунки по горизонтали на веб-странице.

Достаточно просто я просто поместил изображение в DOM и использовал преобразования CSS3 с откатом к анимации jQuery для браузеров, которые еще не поддерживают преобразования CSS.

Все выглядело довольно хорошо. У меня было несколько облаков, которые плавно двигались по странице.

Затем я продолжал получать просьбы от дизайнера замедлить движение вниз... вниз.

Поскольку браузеры не выполняют субпиксельный рендеринг для объектов DOM, анимация выполняется со скоростью 6 кадров в секунду.

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

Моя демонстрация быстрой анимации на холсте (в ней нет точного времени для движений, исправьтесь. :- р )


person David Murdoch    schedule 14.06.2011    source источник
comment
Можешь сделать ctx.translate(.1 * x, 0) или что-то в этом роде?   -  person Gabe    schedule 15.06.2011
comment
Отлично смотрится в IE9 и в FF. А вот в Хроме не все так хорошо.   -  person gilly3    schedule 15.06.2011
comment
хм, я тестировал в Chrome (думая, что это будет лучший из всех для этого). Может быть, это проблема вебкита?   -  person David Murdoch    schedule 15.06.2011


Ответы (6)


Для старых браузеров вы можете анимировать спрайт. Создайте примерно 4 версии вашего изображения, каждая из которых будет смещена на 0,25 пикселя влево от предыдущей. Вставьте их вместе в спрайт, а затем анимируйте положение фона.

function moveClouds(n)
{
    var v = (n % 4) * 417;
    var h = Math.ceil(n / 4);
    clouds.style.backgroundPosition = h + " " + v;
}
person gilly3    schedule 14.06.2011

Это известная проблема Chrome, описанная на странице http://code.google.com/p/chromium/issues/detail?id=7508

до сих пор нет решения или обходного пути для этого ..

person Gabriele Petrioli    schedule 14.06.2011

Здесь можно сделать хак, но он довольно уродлив.

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

person dmp    schedule 25.07.2011

Я немного попробовал ваш пример кода, и мне кажется, что более медленная прокрутка кажется очень плавной:

ctx.drawImage(img, left -= 0.0025, 0, 633, 417);    

Я использую браузер Chrome на Mac.

person marco    schedule 14.06.2011
comment
Chrome 12 в Windows XP все еще тормозит, просто в 10 раз медленнее. - person recursive; 15.06.2011

Насколько я понимаю... не много сделано браузерного тестирования сглаживания. Он срабатывает, когда drawImage(img1, x,y,width,height) x или y не являются целыми числами. И срабатывает, когда теги холста width="600" height="600" больше, чем style="width:600; height:600"

Установка стиля на 1/2 размера холста предполагает принудительное сглаживание. В прошлый раз я исследовал тему. Я бы не стал предполагать, что браузеры будут реализовывать стандарт на 100%.

Примечание: для зеленого экрана видео сглаживание важно для удаления артефактов.

Обновление: В вашем примере я не получаю сглаживание с использованием хрома, как с Firefox. последние версии обоих браузеров для Win XP. Firefox fps мучительно медленный на вашем примере.

Еще одно обновление Установка размера стиля холста на 1/3 размера холста [3 пикселя холста для 1 пикселя экрана], кажется, заставляет работать субпиксельный рендеринг ... но снижение производительности может быть связано с большой, чтобы сделать это таким образом.

Sub-pixel canvas test.<br/>
<canvas id="canvas" width="317" height="351" 
style="border:solid 1px  #000; width:100px; height:100px"></canvas>

Извините, это не тот ответ, который вы на самом деле хотели.

person Wayne    schedule 14.06.2011
comment
Разве сглаживание не является отдельной проблемой от субпиксельного рендеринга? То есть субпиксельный рендеринг — это способ сглаживания или его улучшения, но сглаживание можно выполнять и без субпиксельного рендеринга. - person Pointy; 15.06.2011
comment
@Pointy, я не совсем уверен в правильном использовании терминов ... поэтому не стесняйтесь редактировать мой вопрос, если вы чувствуете, что я использую их неправильно. - person David Murdoch; 15.06.2011
comment
Я думаю, что ваш ответ в порядке, но я просто хотел уточнить. Я на самом деле не эксперт по рендерингу или что-то в этом роде, но я довольно стар, и я знаю, что люди говорили о сглаживании экранной графики еще тогда, когда ЖК-дисплеи были научной фантастикой :-) - person Pointy; 15.06.2011

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

Согласно предварительному стандарту html5, браузер должен решить, хочет ли он выполнять сглаживание или нет.

person axkibe    schedule 14.06.2011