Обновление данных изображения с использованием putImageData для измененного элемента canvas - PullRequest
1 голос
/ 08 июля 2010

У меня есть статическое изображение (png), которое я рисую на элементе canvas, используя drawImage.

var _canvas = null;
var _context = null;
var _curImageData;

function copyImageToCanvas(aImg)
{
  _canvas = document.getElementById("canvas");
  var w = aImg.naturalWidth;
  var h = aImg.naturalHeight;
  _canvas.width = w;
  _canvas.height = h;

  _context = _canvas.getContext("2d");
  _context.clearRect(0, 0, w, h);
  _context.drawImage(aImg, 0, 0);

  _curImageData = _context.getImageData(0, 0, w, h);
}

Затем я манипулирую пикселями данных изображения (устанавливая непрозрачность 255 или 0 в зависимости от значения пикселя), а затем обновляю холст с помощью putImageData.

function updateImage(maxPixelValToShow)
{
  for (var x = 0; x < _curImageData.width; x++)
    for (var y = 0; y < _curImageData.height; y++)
    {
        var offset = (y * _curImageData.width + x) * 4;
        var r = _curImageData.data[offset];
        var g = _curImageData.data[offset + 1];
        var b = _curImageData.data[offset + 2];
        var a = _curImageData.data[offset + 3];
        var pixelNum = ((g * 255) + b);

        //if greater than max or black/no data
        if (pixelNum > maxPixelValToShow || (!r && !g && !b)) {
            _curImageData.data[offset + 3] = 0;
        } else {
            _curImageData.data[offset + 3] = 255;
        }

    }
  _context.putImageData(_curImageData, 0, 0);
}

И все это прекрасно работает. У меня возникает проблема, когда я создаю холст, который в два раза больше моего изображения (или вдвое меньше), и рисую изображение, чтобы оно соответствовало размеру холста.

function copyImageToCanvas(aImg)
{
  _canvas = document.getElementById("canvas");
  var w = aImg.naturalWidth * 2;  //double the size!
  var h = aImg.naturalHeight * 2; //double the size!

  _canvas.width = w;
  _canvas.height = h;

  _context = _canvas.getContext("2d");
  _context.clearRect(0, 0, w, h);
  _context.drawImage(aImg, 0, 0, w, h);

  _curImageData = _context.getImageData(0, 0, w, h);
}

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

Вот несколько изображений, чтобы показать, что генерируется:

Исходное изображение

Исходное изображение после моего updateImage вызова функции

Изображение с измененным размером

Изображение с измененным размером после моего updateImage вызова функции

[Решение] Спасибо Адам и Сунетос, это была проблема. Он работал нормально, когда я установил один холст для хранения данных исходного файла и выполнения манипуляций с пикселями, а другой только для отображения. Фрагмент кода ниже:

function updateImage(maxPixelValToShow) {
  //manipulate the _workingContext data

  _workingContext.putImageData(_curImageData, 0, 0);
  _displayContext.clearRect(0, 0, _workingCanvas.width*_scale, _workingCanvas.height*_scale);
  _displayContext.drawImage(_workingCanvas, 0, 0, _workingCanvas.width*_scale, _workingCanvas.height*_scale);
}

1 Ответ

1 голос
/ 08 июля 2010

Похоже, что сглаживание изображения используется браузером при масштабировании изображения в drawImage () сглаживает края вашей фигуры, вызывая новые промежуточные значения цвета вокруг края, которые не обрабатываются вашей функцией updateImage ().Как прокомментировал Адам, вы должны применить свою логику updateImage () к неизмененным исходным пикселям, а затем масштабировать ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...