You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

p5.js问题:复制的图像为何被压缩且重复?

像素复制后Buffer显示异常问题

我正在为学校作业做像素数据处理,需要把一张图像的像素数据复制到buffer里,但buffer显示出大幅压缩且包含两张相同图像的异常(左侧是原图像,右侧是buffer,灰色区域是背景):

像素复制异常显示

控制台确认过,buffer和原图像的分辨率都是512x512,但显示还是异常。我用的复制代码如下:

imgs[0].loadPixels();
avgImg.loadPixels();
    
    for(var y = 0; y < imgs[0].height; ++y) {
        for(var x = 0; x < imgs[0].width; ++x) {
            var index = (y * imgs[0].width + x) * 4;
            avgImg.pixels[index] = imgs[0].pixels[index];
            avgImg.pixels[index + 1] = imgs[0].pixels[index + 1]
            avgImg.pixels[index + 2] = imgs[0].pixels[index + 2]
            avgImg.pixels[index + 3] = imgs[0].pixels[index + 3]
        }
    }

    avgImg.updatePixels();
    image(avgImg, avgImg.width, 0);

请问哪里操作出错了?


问题原因及解决方法

这种异常是像素数组的行对齐(stride)不匹配导致的。在Processing/p5.js这类框架中,像素数组的实际长度可能因底层画布的内存对齐要求,比width*height*4更大——比如部分环境会把每行像素的字节数向上取整到特定倍数,此时直接用原图像的width计算目标图像的像素索引,会导致目标图像每行像素提前结束,后续像素挤入下一行,最终出现压缩、重复的显示问题。

解决办法:

  • 方法一:用内置copy()方法替代手动循环(最简便可靠)
    若只是单纯复制像素,框架内置的copy()会自动处理行对齐问题,无需手动遍历:

    imgs[0].loadPixels();
    avgImg.loadPixels();
    // 复制原图像全部像素到avgImg
    imgs[0].copy(0, 0, imgs[0].width, imgs[0].height, 0, 0, avgImg.width, avgImg.height);
    avgImg.updatePixels();
    image(avgImg, avgImg.width, 0);
    
  • 方法二:手动循环时区分原图像与目标图像的width
    若必须手动处理像素,计算目标图像的索引时要使用自身的width,而非原图像的width:

    imgs[0].loadPixels();
    avgImg.loadPixels();
    
    for(var y = 0; y < imgs[0].height; ++y) {
        for(var x = 0; x < imgs[0].width; ++x) {
            // 原图像索引用原图像width计算
            var srcIndex = (y * imgs[0].width + x) * 4;
            // 目标图像索引用目标图像width计算
            var dstIndex = (y * avgImg.width + x) * 4;
            avgImg.pixels[dstIndex] = imgs[0].pixels[srcIndex];
            avgImg.pixels[dstIndex + 1] = imgs[0].pixels[srcIndex + 1];
            avgImg.pixels[dstIndex + 2] = imgs[0].pixels[srcIndex + 2];
            avgImg.pixels[dstIndex + 3] = imgs[0].pixels[srcIndex + 3];
        }
    }
    
    avgImg.updatePixels();
    image(avgImg, avgImg.width, 0);
    

另外需要确认avgImg的创建方式正确——比如在p5.js中,需通过createGraphics(512, 512)创建,避免因创建方式错误导致实际画布尺寸与声明的width/height不符。

内容的提问来源于stack exchange,提问作者Ryolu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 10:40:36