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>
Другие вопросы по тегам