代码之家  ›  专栏  ›  技术社区  ›  atogle

在调整大小的画布元素上使用putimagedata更新图像数据

  •  1
  • atogle  · 技术社区  · 14 年前

    我有一个静态图像(PNG),在画布元素上使用 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 功能。有人知道a)为什么会发生这种情况b)我能做些什么?

    以下是一些显示正在生成的内容的图像:

    The original image

    The original image after my updateImage function call

    The resized image

    The resized image after my updateImage function call

    [解决方案] 多谢亚当和苏内托斯,这就是问题所在。一旦我设置了一个画布来存储原始文件数据并进行像素操作,另一个画布仅用于显示,它就工作得很好。下面的代码段:

    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 回复  |  直到 14 年前
        1
  •  1
  •   sunetos    14 年前

    它看起来像浏览器在DrawImage()中放大图像时使用的图像平滑处理消除了形状边缘的锯齿,导致边缘周围新的中间颜色值不由UpdateImage()函数处理。就像亚当评论的那样,您应该对未修改的原始像素应用updateImage()逻辑,并且 然后 缩放它。

    推荐文章