HTML5 - Canvas, drawImage() рисует изображение размытым
Я пытаюсь нарисовать следующее изображение на холсте, но оно выглядит размытым, несмотря на определение размера холста. Как вы можете видеть ниже, изображение четкое и четкое, тогда как на холсте оно размытое и пиксельное.
![enter image description here]()
и вот как это выглядит (левый является оригиналом, а правый - нарисованным холстом и размытым).
![enter image description here]()
Что я делаю не так?
console.log('Hello world')
var c = document.getElementById('canvas')
var ctx = c.getContext('2d')
var playerImg = new Image()
// http://i.imgur.com/ruZv0dl.png sees a CLEAR, CRISP image
playerImg.src = 'http://i.imgur.com/ruZv0dl.png'
playerImg.width = 32
playerImg.height = 32
playerImg.onload = function() {
ctx.drawImage(playerImg, 0, 0, 32, 32);
};
#canvas {
background: #ABABAB;
position: relative;
height: 352px;
width: 512px;
z-index: 1;
}
<canvas id="canvas" height="352" width="521"></canvas>
Ответы
Ответ 1
Причина этого происходит из-за Anti Aliasing.
Просто установите imageSmoothingEnabled
как false
context.imageSmoothingEnabled = false;
Вот jsFiddle verson
jsFiddle: https://jsfiddle.net/mt8sk9cb/
var c = document.getElementById('canvas')
var ctx = c.getContext('2d')
var playerImg = new Image()
// http://i.imgur.com/ruZv0dl.png sees a CLEAR, CRISP image
playerImg.src = 'http://i.imgur.com/ruZv0dl.png'
playerImg.onload = function() {
ctx.imageSmoothingEnabled = false;
ctx.drawImage(playerImg, 0, 0, 256, 256);
};
Ответ 2
Ваша проблема заключается в том, что ваши ограничения css canvas{width:512}
и свойство canvas width=521
заставят ваш браузер перепрограммировать весь холст.
Чтобы избежать этого, удалите эти объявления css.
var c = document.getElementById('canvas')
var ctx = c.getContext('2d')
var playerImg = new Image()
// http://i.imgur.com/ruZv0dl.png sees a CLEAR, CRISP image
playerImg.src = 'http://i.imgur.com/ruZv0dl.png'
playerImg.width = 32
playerImg.height = 32
playerImg.onload = function() {
ctx.drawImage(playerImg, 0, 0, 32, 32);
};
#canvas {
background: #ABABAB;
position: relative;
z-index: 1;
}
<canvas id="canvas" height="352" width="521"></canvas>
Ответ 3
Следующий код работает для меня:
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width, img.height);
};
img.src = e.target.result; // your src
Ответ 4
В дополнение к ответу @canvas.
context.imageSmoothingEnabled = false;
Отлично работает. Но в моем случае при изменении размера холста это свойство возвращается к значению true.
window.addEventListener('resize', function(e){
context.imageSmoothingEnabled = false;
}, false)
Ответ 5
Поскольку я сталкивался с этим более ранним постом по некоторым из моих проблем, здесь еще больше понимания размытых изображений для наложения поверх решения 'imageSmoothingEnabled'.
Это более конкретно для случая использования рендеринга для конкретного монитора, и только некоторые люди столкнулись с этой проблемой, если они пытались визуализировать графику с качеством сетчатки на холсте с неутешительными результатами.
По сути, мониторы высокой плотности означают, что вашему холсту необходимо учитывать эту дополнительную плотность пикселей. Если вы ничего не сделаете, canvas будет отображать только достаточное количество информации о пикселях в своем контексте, чтобы учесть соотношение пикселей 1.
Поэтому для многих современных мониторов, у которых есть коэффициенты> 1, вы должны изменить свой контекст холста, чтобы учесть эту дополнительную информацию, но сохранить свой холст нормальной ширины и высоты.
Для этого вы просто устанавливаете ширину и высоту контекста рендеринга равными: целевой ширине и высоте * window.devicePixelRatio.
canvas.width = target width * window.devicePixelRatio;
canvas.height = target height * window.devicePixelRatio;
Затем вы устанавливаете стиль холста, чтобы размер холста соответствовал нормальным размерам:
canvas.style.width = '${target width}px';
canvas.style.height = '${target height}px';
В последний раз вы отображаете изображение с максимальным размером контекста, который позволяет изображение. В некоторых случаях (например, при визуализации изображений в формате SVG) вы все равно можете получить лучшее качество изображения, визуализируя изображение с размерами в пикселях:
ctx.drawImage(
img, 0, 0,
img.width * window.devicePixelRatio,
img.height * window.devicePixelRatio
);
Итак, чтобы показать это явление, я сделал скрипку. Вы НЕ увидите разницы в качестве холста, если вы используете монитор pixelRatio, близкий к 1.
https://jsfiddle.net/ufjm50p9/2/
Ответ 6
Простой наконечник: нарисуйте с .5 в x и y. например drawImage (, 0.5, 0.5): D Там вы получите четкие края: D