drawImage() на холсте насыщает цвета и портит альфа
РЕДАКТИРОВАТЬ: D'OH! Суть этого вопроса в основном не имеет значения, потому что я обнаружил свою глупую ошибку, которая состояла в том, что мой холст перерисовывался по таймеру, и я не очищал холст между рисованиями. Это имело эффект затемнения любых полупрозрачных областей до полной непрозрачности.
Сейчас занимаюсь:
mainContext.clearRect ( 0 , 0 , 320 , 480 );
перед каждым кадром рисуй.
Небольшая загадка, которая все еще остается, заключается в том, почему рисование объекта над самим собой также затемняет / насыщает области изображения, которые были полностью непрозрачными для начала.
РЕДАКТИРОВАТЬ: я добавил картинку. В нижней области показано изображение, загруженное в элемент (который выглядит так же, как изображение в моей программе рисования). (Img можно скачать здесь. Я изменил его размер, чтобы сделать снимок экрана ниже, но я получаю тот же результат с исходным загруженным изображением без изменений.) Верхняя рамка - это холст с drawImage() из того же элемента. Я не уверен, что "уменьшенная глубина цвета" является правильным описанием сейчас. Кажется, что это меняет цвета - вы можете видеть, что на холсте цвета более насыщенные. Кроме того, это также не обрабатывает альфа правильно. То, что я описал раньше как "полосатость", теперь я понимаю, что в основном происходило в областях с более высоким уровнем прозрачности исходного изображения.
РЕДАКТИРОВАТЬ: прогресс был достигнут.
Я вижу, что если я рисую полностью непрозрачное фоновое изображение на холсте, то когда я рисую изображения с прозрачностью поверх него, получается правильная альфа.
Я попытался нарисовать прямоугольник, заполненный цветом в качестве фона, но у него все еще была проблема с прозрачностью, когда изображения были нарисованы поверх него. Кажется необходимым нарисовать это непрозрачное изображение внизу.
Это звучит знакомо?
Я также до сих пор не понимаю, почему цвета изображения внутри полотна более насыщенные. Может быть, это гамма-коррекция, похожая на цветовые различия между Mac и ПК?
У меня очень простая страница с одним элементом canvas. Я загружаю 32-битный файл.png. Я загружаю файл двумя способами: один раз, создав новый объект Image () и установив его src, и один раз создав элемент с тем же источником.
Этот элемент на странице показывает мое изображение с правильными цветами, красиво округленными углами и так далее.
Но когда я рисую изображение на холсте, оно, похоже, теряет глубину цвета. В частности, оно, похоже, уменьшено с изображения в 32 bpp до изображения в 8 bpp (с использованием некоторой палитры по умолчанию). Я вижу сильную полосу на областях градиента, и альфа-канал теряется, как видно из блочной пикселизации углов, которые были гладкими на исходном изображении.
Я получаю одинаковые результаты как в Chrome, так и в Firefox (обе последние версии).
Я получаю изображение на холсте с
context.drawImage( theImage, 0, 0 );
За theImage
в приведенном выше коде я пробовал оба Image()
объект и <img>
элемент (тот, который уже показывает хорошую версию изображения в другом месте на странице). В обоих случаях я получаю одинаковый результат - изображение, по-видимому, было уменьшено до 8 бит / с.
Мой холст настроен как:
<canvas class="MainCanvas" width="320" height="480"></canvas>
Как я уже сказал, мои изображения загружаются с использованием класса Image ():
var image = new Image();
image.src = "images/myimage.png";
и один как элемент:
<img class="OtherImage" src="images/myimage.png" />
И это почти все.
Тот факт, что изображение хорошо показывает в <img>
Кажется, что элемент указывает на то, что проблема не в изображении или загрузке изображения, а в drawImage()
позвони или сам холст.
Я задаюсь вопросом, мог ли бы мой холст или его контекст быть установлен в этот режим уменьшенной глубины цвета, но я не мог найти что-нибудь о такой настройке.
(Я обнаружил, что для того, чтобы холст не сбивал с толку автоматическое масштабирование изображения, необходимо установить размер холста, используя атрибуты "width" и "height", как указано выше, а не в css. Я надеюсь, что Исправить эту проблему глубины цвета - это то же самое, что я просто не смог найти...)
1 ответ
Вот еще данные для вас...
Мне не удалось воспроизвести проблемы с цветом в Win7 + ( IE10 | FF21 | Chrome27)
Примечание на HTML-холсте:
Естественный фон холста прозрачен. Поэтому, когда вы рисуете полупрозрачное изображение на холсте, должна быть попытка смешивания цветов в полупрозрачных областях с тем, что находится внизу (фон тела?).
Когда вы рисуете непрозрачное изображение + полупрозрачное изображение, вы будете насыщать полупрозрачные пиксели, а также добавляете пиксельный цвет на фоне непрозрачного изображения. Я думаю, что это приведет к искажению цвета, а не к его исправлению. Любопытно?
Заполнение холста непрозрачным (белым?) Прямоугольником перед рисованием вашего полупрозрачного изображения поможет контролировать фон, на котором ваше изображение смешано с цветом.
Во всяком случае, надеюсь, что это поможет обнаружить то, что болит ваши изображения!:)
Вот код и скрипка: http://jsfiddle.net/m1erickson/KpAyq/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: white; padding:10px; }
canvas{border:1px solid red;}
img{border:1px solid blue;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var image=document.createElement("img");
image.onload=function(){
ctx.drawImage(image,0,0);
}
image.src="https://dl.dropboxusercontent.com/u/139992952/stackru/molecule1.png";
}); // end $(function(){});
</script>
</head>
<body>
<p>Left==canvas, Right==img</p>
<canvas id="canvas" width=256 height=275></canvas>
<img src="https://dl.dropboxusercontent.com/u/139992952/stackru/molecule1.png" width=256 height=275>
</body>
</html>