Холст drawImage качество
Вот изображение .png(справа) и элемент холста, на который я нарисовал изображение (слева). Можете ли вы заметить разницу в качестве? Холст отображает изображение с заметной потерей качества. Что мы можем сделать?
Я наблюдал этот результат в Chrome и IE9. Другие, вероятно, сделают то же самое.
Как я визуализирую изображение довольно обычным образом: в script я создаю новый объект Image()
, после его загрузки я вызываю
context.drawImage(myimage, x, y);
![Right: What I want, Left: What I get]()
EDIT:
Это начальное изображение, которое я наблюдал на холсте:
![In more detail: What I got first]()
И вот что делает холст после того, как я написал:
context.drawImage(myimage,parseInt(x),parseInt(y));
![In more detail: What I get with rounded coordinates]()
Что я могу сказать, отличный ответ. Sharpshooting в лучшем виде. Шляпа для вас.
EDIT2:
Я попробовал context.drawImage(myimage, parseInt(x) + 0.5, parseInt(y)+ 0.5);
, вот результат:
![In more detail: Worst case]()
Я думаю, что это хуже, чем первый. Я наблюдал это на хроме, на IE9 он несколько и так же плохой.
Ответы
Ответ 1
Я только что создал наложение обоих изображений, чтобы они нейтрализовали друг друга.
Это не сработало, у меня были трудности с ребрами.
![overlayed image]()
Пожалуйста, проверьте, являются ли ваши координаты 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);
EDIT:
Отметьте эту страницу в Html5Rocks!
Ответ 2
Я знаю, что это уже ответили, но я хочу дать больше информации, чтобы поговорить о том, что происходит здесь и что можно сделать.
Это происходит из-за сглаживания изображения, которое по умолчанию позволяет сглаживать алгоритмы, такие как билинейное /trilieaner/bicubic на холсте, по умолчанию, тогда как то, что вы хотите, называется ближайшим соседом.
В спецификации недавно добавлено свойство с именем imageSmoothingEnabled
, которое по умолчанию равно true
и определяет, будут ли образы, нарисованные на нецелочисленных координатах или нарисованных масштабированных, использовать более плавный алгоритм. Если он установлен на false
, то используется ближайший сосед, создающий менее плавное изображение и вместо этого просто создавая большие пиксели.
Сглаживание изображений только недавно было добавлено в спецификацию холста и не поддерживается всеми браузерами, но некоторые браузеры внедрили версии этого префикса. В контексте существует mozImageSmoothingEnabled
в Firefox и webkitImageSmoothingEnabled
в браузерах Chrome и Safari, а установка их в false приведет к сбою в сглаживании. К сожалению, на момент написания статьи IE9 и Opera не реализовали это свойство, префикс поставщика или иначе.
В общем, вам просто нужно следовать двум правилам:
- Если вы масштабируете холст, вам нужно отключить сглаживание изображения или масштабировать его, используя интерполяцию ближайшего соседа. Есть несколько алгоритмов, чтобы сделать это вручную прямо сейчас, и это то, что делают указанные выше параметры.
- Если вы не используете целые координаты, вы получите ту же проблему, и у нее будет такое же решение. Если вышеуказанных опций не существует в вашем браузере, вам нужно вернуться к целым координатам
(x | 0, y | 0)
Где x | 0
полы x
быстро, однако не будет работать с номерами, превышающими 2,147,483,647: наибольшее 32-разрядное целое число со знаком.
Будем надеяться, что ваши координаты не превышают этого!
Ответ 3
Я думаю, что эта ссылка будет полной. Я сделал то же самое, но в моем случае я даю вес и высоту холста динамически с помощью javascript. Затем я дал высоту и ширину холсту, когда я его объявляю. Это решает проблему.