从 jpg / png 加载像素不正确处理

Posted

技术标签:

【中文标题】从 jpg / png 加载像素不正确处理【英文标题】:loadpixels from jpg / png incorrect processing 【发布时间】:2022-01-05 07:57:12 【问题描述】:

我正在尝试使用图像的底层颜色在图像上绘制网格以填充圆圈。但是有些像素没有得到正确的颜色。 在这种情况下,圆圈被绘制成白色,但它们不应该被绘制成白色......

请参阅下面的代码:

import processing.pdf.*;

PImage img;
color background = color(255);

void setup() 
  size(1038, 525);
  ellipseMode(CORNER);
  noStroke();

  //img = loadImage("noise2.jpg");
  //img = loadImage("air.png");
  img = loadImage("accidents.png");

  image(img, 0, 0, width, height);
  visualGrid(20, 0.4, false);


//void draw() 
//  fill(noise.get(mouseX, mouseY));
//  rect(width - 100, height - 100, 100, 100);
//

void visualGrid(int circleSize, float fillSmoothing, boolean debug) 
  float halfCircle = circleSize / 2.0;
  int amountX = floor(width / circleSize);
  int amountY = floor(height / circleSize);
  amountY += floor(amountY * 0.1);
  
  float offsetX = (width - (amountX * circleSize  + halfCircle)) / 2 + halfCircle;
  float offsetY = (height - amountY * circleSize + amountY * circleSize * 0.1) / 2;
  
  for (int x = 0; x < amountX; x++) 
    for (int y = 0; y < amountY; y++) 
      float styledOffsetX = (y % 2 == 0) ? offsetX - halfCircle : offsetX;
      float xpos = x * circleSize + styledOffsetX;
      float ypos = circleSize * 0.9 * y + offsetY;
      
      int sectionSize = round(circleSize * fillSmoothing);
      float sectionOffset = (circleSize - sectionSize) / 2;
      
      color c = getAvgImgColor(img.get(round(xpos + sectionOffset), round(ypos + sectionOffset), sectionSize, sectionSize));
      //fill(noise.get(round(xpos), round(ypos)));
      
      if(debug) 
        stroke(255, 0, 255);
        strokeWeight(1);
      
      
      fill(c);
      ellipse(xpos, ypos, circleSize, circleSize);
      
      if(debug) 
        noStroke();
        fill(255, 0, 255);
        rect(round(xpos + sectionOffset), round(ypos + sectionOffset), sectionSize, sectionSize);
      
    
  


color getAvgImgColor(PImage section) 
  
  section.loadPixels();
  
  int avgR = 0, avgG = 0, avgB = 0;
  int totalPixels = section.pixels.length;
  
  for (int i = 0; i < totalPixels; i++)  
    color pixel = section.pixels[i];
    //if(pixel == background) continue;
    
    avgR += red(pixel);
    avgG += green(pixel);
    avgB += blue(pixel);
   
  
  return color(
    round(avgR / totalPixels),
    round(avgG / totalPixels),
    round(avgB / totalPixels)
  );

这是我在相关图像上绘制网格时得到的结果: 正如您在圆圈区域中看到的那样,并非所有圆圈都应该用白色填充...这种情况发生在比圆圈更多的地方,只需将此图像与下面的图像进行比较即可。

下面我会上传原图,大家可以用它来调试。

【问题讨论】:

【参考方案1】:

您的草图 (1038 x 525) 和您正在采样的图像 (2076 x 1048) 的尺寸不匹配,这可能解释了这种不对齐。

如果size(2076, 1048) 不是一个选项,请在将图像加载到setup() 后尝试调整其大小:

...
img = loadImage("accidents.png");
img.resize(width, height);
...

【讨论】:

以上是关于从 jpg / png 加载像素不正确处理的主要内容,如果未能解决你的问题,请参考以下文章

C#位图从像素中读取不正确的颜色

如何从imageview中的png获取特定颜色的所有像素

如果是 JPG 图像,QLabel() 将不会加载像素图

性能优化的几个小点

Unity像素艺术多个精灵没有正确切割

ImageMagick 不会将 .png 转换为 .jpg