提问者:小点点

绘图图像(PGraphics)给出不需要的关于x轴镜像的双图像。处理3


该代码应该淡出并将窗口的图像复制到缓冲区f,然后将f绘制回窗口,但进行平移、旋转和缩放。当您将插入电视的相机指向电视时,我试图创建一个类似反馈循环的效果。

我已经尝试了我能想到的一切,记录了我能想到的每一个变量,但仍然看起来image(f,0,0)做错了或出乎意料。

我错过了什么?

关于x轴的双像镜图片:

PGraphics f;
int rect_size;
int midX;
int midY;

 void setup(){
  size(1000, 1000, P2D);
  f = createGraphics(width, height, P2D);
  midX = width/2;
  midY = height/2;
  rect_size = 300;
  imageMode(CENTER);
  rectMode(CENTER);
  smooth();
  background(0,0,0);
  fill(0,0);
  stroke(255,255);
}

void draw(){
  fade_and_copy_pixels(f); //fades window pixels and then copies pixels to f
  background(0,0,0);//without this the corners dont get repainted.
  //transform display window (instead of f)
  pushMatrix();
  float scaling = 0.90; // x>1 makes image bigger
  float rot = 5; //angle in degrees
  translate(midX,midY); //makes it so rotations are always around the center
  rotate(radians(rot));
  scale(scaling);
  imageMode(CENTER);
  image(f,0,0); //weird double image must have something not working around here
  popMatrix();//returns window matrix to normal
  int x = mouseX;
  int y = mouseY;
  rectMode(CENTER);
  rect(x,y,rect_size,rect_size);
}

//fades window pixels and then copies pixels to f
void fade_and_copy_pixels(PGraphics f){
  loadPixels();  //load windows pixels. dont need because I am only reading pixels?
  f.loadPixels(); //loads feedback loops pixels
  // Loop through every pixel in window
  //it is faster to grab data from pixels[] array, so dont use get and set, use this

  for (int i = 0; i < pixels.length; i++) {
      //////////////FADE PIXELS in window and COPY to f:///////////////
      color p = pixels[i];

      //get color values, mask then shift
      int r = (p & 0x00FF0000) >> 16;
      int g = (p & 0x0000FF00) >> 8;
      int b =  p & 0x000000FF; //no need for shifting

      // reduce value for each color proportional 
      // between fade_amount between 0-1 for 0 being totallty transparent, and 1 totally none
      // min is 0.0039 (when using floor function and 255 as molorModes for colors)
      float fade_percent= 0.005; //0.05 = 5%

      int r_new = floor(float(r) - (float(r) * fade_percent));
      int g_new = floor(float(g) - (float(g) * fade_percent));
      int b_new = floor(float(b) - (float(b) * fade_percent));
      //maybe later rewrite in a way to save what the difference is and round it differently, like maybe faster at first and slow later, 
       //round doesn't work because it never first subtracts one to get the ball rolling
      //floor has a minimum of always subtracting 1 from each value each time. cant just subtract 1 ever n loops
      //keep a list of all the pixel as floats? too much memory?
      //ill stick with floor for now
      // the lowest percent that will make a difference with floor is 0.0039?... because thats slightly more than 1/255

      //shift back and or together
      p = 0xFF000000 | (r_new << 16) | (g_new << 8) | b_new; // or-ing all the new hex together back into AARRGGBB

      f.pixels[i] = p;
      ////////pixels now copied
  }
  f.updatePixels(); 

}

共2个答案

匿名用户

这是一个奇怪的问题。但是让我们从一个更简单的隔离问题的MCVE开始:

PGraphics f;
void setup() {
  size(500, 500, P2D);
  f = createGraphics(width, height, P2D);
}

void draw() {
  background(0);
  rect(mouseX, mouseY, 100, 100);
  copyPixels(f); 
  image(f, 0, 0);
}

void copyPixels(PGraphics f) {
  loadPixels();
  f.loadPixels(); 

  for (int i = 0; i < pixels.length; i++) {
    color p = pixels[i];
    f.pixels[i] = p;
  }
  f.updatePixels();
}

这段代码展示了与您的代码相同的问题,没有任何额外的逻辑。我希望这段代码在鼠标所在的位置显示一个矩形,但它在X轴上反射的位置显示一个矩形。如果鼠标在窗口的顶部,矩形在窗口的底部,反之亦然。

我认为这是由P2D渲染器是OpenGL引起的,它有一个反转的Y轴(0在底部而不是顶部)。所以当你复制像素时,它似乎是从屏幕空间到OpenGL空间…什么的。不过,这看起来肯定有问题。

目前,有两件事似乎可以解决这个问题。首先,您可以使用默认渲染器而不是P2D。这似乎解决了问题。

或者您可以在CopyPixels()函数中去掉for循环,现在只执行f.像素=像素;。这似乎也解决了问题,但再次感觉很有问题。

如果别人(呼叫乔治)明天还没有给出更好的解释,我会在处理的GitHub上提交bug。(如果你愿意,我可以为你做。)

编辑:我在这里提交了一个问题,所以希望我们能在接下来的几天里收到开发人员的回复。

编辑二:看起来已经实施了一个修复程序,应该可以在下一个处理版本中使用。如果您现在需要它,您可以随时从源代码构建处理。

匿名用户

一个更容易的,像魅力一样工作:

添加f. startinDraw();之前和f.endDraw();使用f后:

loadPixels();  //load windows pixels. dont need because I am only reading pixels?
  f.loadPixels(); //loads feedback loops pixels
  // Loop through every pixel in window
  //it is faster to grab data from pixels[] array, so dont use get and set, use this

  f.beginDraw();

f.updatePixels(); 
  f.endDraw();

处理必须知道它何时在缓冲区中绘制,何时不绘制。

在这张图片中你可以看到这是有效的