Холст drawImage качество

Вот изображение.png (справа) и элемент canvas, на котором я нарисовал изображение (слева). Вы можете заметить разницу в качестве? Холст рендерит изображение с заметной потерей качества. Что мы можем сделать?

Я наблюдал этот результат на Chrome и IE9. Другие, вероятно, сделают то же самое. То, как я отрисовываю изображение, довольно обычное: в скрипте я создаю новый Image() объект, после загрузки я звоню
context.drawImage(myimage, x, y);

Справа: что я хочу, слева: что я получу

РЕДАКТИРОВАТЬ:

Это исходное изображение, которое я заметил на холсте:
Более подробно: что я получил первым

А вот что рендер делает после того, как я написал:
context.drawImage(myimage,parseInt(x),parseInt(y));
Более подробно: что я получаю с округленными координатами

Что тут скажешь, отличный ответ мужик. Меткое стрельба в лучшем виде. Шляпа снята для вас.

EDIT2:

Я старался context.drawImage(myimage, parseInt(x) + 0.5, parseInt(y)+ 0.5);вот результат:

Более подробно: худший случай

Я думаю, что это хуже, чем первый. Я наблюдал это на chrome, на IE9 это так же плохо.

3 ответа

Решение

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

наложенное изображение

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

context.drawImage(myimage, parseInt(x), parseInt(y));

Если это тоже не работает, попробуйте использовать целочисленное значение + 0,5
Я знаю, что для реализации OpenGL, вы должны использовать координаты с 0,5, чтобы попасть в центр пикселя.

context.drawImage(myimage, parseInt(x)+0.5, parseInt(y)+0.5);


РЕДАКТИРОВАТЬ:

Проверьте эту страницу на Html5Rocks!

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


Это происходит из-за сглаживания изображения, которое по умолчанию использует алгоритмы сглаживания, такие как bilinear / trilieaner / bicubic на холсте, тогда как то, что вы хотите, называется ближайшим соседом.

Спецификация недавно добавила свойство под названием imageSmoothingEnabled, который по умолчанию true и определяет, будут ли изображения, нарисованные по нецелым координатам или нарисованные в масштабе, использовать более плавный алгоритм. Если установлено false затем используется ближайший сосед, создавая менее плавное изображение и вместо этого просто создавая пиксели большего размера.

Сглаживание изображения было добавлено только недавно в спецификацию холста и поддерживается не всеми браузерами, но некоторые браузеры реализовали версии этого свойства с префиксом поставщика. В контексте существует mozImageSmoothingEnabled в Firefox и webkitImageSmoothingEnabled в Chrome и Safari, если задать для них значение false, сглаживание не произойдет. К сожалению, на момент написания статьи IE9 и Opera не реализовали это свойство, с префиксом поставщика или иным образом.

В общем, вам просто нужно следовать двум правилам:

  1. Если вы масштабируете холст, вам нужно отключить сглаживание изображения или масштабировать его, используя интерполяцию ближайшего соседа. Есть несколько алгоритмов, чтобы сделать это вручную прямо сейчас, и это то, что делают вышеупомянутые опции.
  2. Если вы не рисуете целочисленные координаты, вы получите ту же проблему, и у нее такое же решение. Если вышеупомянутые опции не существуют в вашем браузере, вам нужно вернуться к целочисленным координатам (x | 0, y | 0)

куда x | 0 этажей x быстро, однако, не будет работать с числами больше 2 147 483 647: наибольшее 32-разрядное целое число со знаком.

Надеюсь, ваши координаты не больше этого!

Я думаю, что эта ссылка поможет полностью. Я сделал то же самое, но в моем случае я динамически определяю вес и рост холста с помощью JavaScript. Затем я объявил холсту высоту и ширину. Это решит проблему.

Другие вопросы по тегам