提问者:小点点

小于1像素的游标会发生什么


我正在将处理脚本重新输入python,以便在gimp-python脚本中使用它。我在strokeWeight(0.3)上遇到问题,这意味着厚度小于1像素。

我遵循了将rgb颜色与alpha混合的建议,但这并不起作用。似乎处理正在做其他事情。我试图在处理源代码中查找strokeWeight函数,但我无法真正理解它。我还试图将strokeWeight为1的颜色值与strokeWeight为0.3的颜色值进行比较,但我也无法理解它。

有人知道当将strokeWeight设置为0.3时,处理会做什么吗?

我使用的脚本是:

String filename = "image2";
String fileext = ".jpg";
String foldername = "./";

// run, after 30 iterations result will be saved automatically
// or press SPACE

int max_display_size = 800; // viewing window size (regardless image size)

/////////////////////////////////////
int n=2000;
float [] cx=new float[n];
float [] cy=new float[n];

PImage img;
int len;

// working buffer
PGraphics buffer; 

String sessionid; 

void setup() {
  sessionid = hex((int)random(0xffff),4);
  img = loadImage(foldername+filename+fileext);

  buffer = createGraphics(img.width, img.height);
  buffer.beginDraw();
  //buffer.noFill();
  //buffer.smooth(8);
  //buffer.strokeWeight(1);
  buffer.strokeWeight(0.3);
  buffer.background(0);
  buffer.endDraw();

  size(300,300);

  len = (img.width<img.height?img.width:img.height)/6;

  background(0);
  for (int i=0; i<n; i++) {
    cx[i] = i; // changed to a none random number for testing 
    cy[i] = i; 
  //for (int i=0;i<n;i++) {
  //  cx[i]=random(img.width);
  //  cy[i]=random(img.height);
  }
}

int tick = 0;

void draw() {  
  buffer.beginDraw();
  for (int i=1;i<n;i++) {
    color c = img.get((int)cx[i], (int)cy[i]);
    buffer.stroke(c);
    buffer.point(cx[i], cy[i]);
    // you can choose channels: red(c), blue(c), green(c), hue(c), saturation(c) or brightness(c)
    cy[i]+=sin(map(hue(c),0,255,0,TWO_PI));
    cx[i]+=cos(map(hue(c),0,255,0,TWO_PI));
  }

  if (frameCount>len) {
    frameCount=0;
    println("iteration: " + tick++);
    //for (int i=0;i<n;i++) {
    //  cx[i]=random(img.width);
    //  cy[i]=random(img.height);
    for (int i=0; i<n; i++) {
      cx[i] = i; // changed to a none random number for testing 
      cy[i] = i;
    }

  }

  buffer.endDraw();
  if(tick == 30) keyPressed();

  image(buffer,0,0,width,height);
}

void keyPressed() {
  buffer.save(foldername + filename + "/res_" + sessionid + hex((int)random(0xffff),4)+"_"+filename+fileext);
  println("image saved");
}


共2个答案

匿名用户

0.3像素的笔画权重意味着像素的3/10将被着色(*),因此,假设路径穿过中间的像素,像素将被绘制为3/10不透明度(可能会对线性/感知进行一些调整)。

(*)当然,如果路径靠近像素的边缘,这可能会少一点,并且相邻像素也会稍微着色。

匿名用户

基于许多评论,目标似乎是使用基本算法对像素进行采样并合成新图像来生成9000x9000图像。

该算法的工作原理如下:

  1. 根据输入图像尺寸分配随机像素位置
  2. 在预先分配的像素位置绘制一个小(亚像素)点
  3. 基于sin()/cos()函数
  4. 的颜色通道(H/S/B/R/G/B)强度到角度映射的曲线上的偏移像素位置

现有的处理脚本可以很容易地适应输出9000x9000图像。在输入图像较小的情况下,可以重新映射坐标:

float remappedX = map(cx[i],0,input.width,0,output.width);
float remappedY = map(cy[i],0,input.height,0,output.height);

以下是发布在顶部的处理草图的修改版本:

String filename = "image2";
String fileext = ".jpg";
String foldername = "./";

// run, after 30 iterations result will be saved automatically
// or press SPACE

/////////////////////////////////////
// number of pixels to sample
int n = 2000;
float[] cx;
float[] cy;

PImage img;
int len;

// working buffer
PGraphics buffer;
// buffer size
int bufferWidth  = 9000;
int bufferHeight = 9000;

String sessionid; 

int tick = 0;

boolean imageAutoSaved = false;

void setup() {
  size(300,300);
  background(0);

  // load image, setup session
  sessionid = hex((int)random(0xffff),4);
  img = loadImage(foldername+filename+fileext);
  len = (img.width<img.height?img.width:img.height)/6;
  // sample each pixel
  n = img.pixels.length;
  cx = new float[n];
  cy = new float[n];
  resetPixelSampling();
  // setup buffer
  buffer = createGraphics(bufferWidth,bufferHeight);
  buffer.beginDraw();
  //buffer.noFill();
  //buffer.smooth(8);
  //buffer.strokeWeight(1);
  buffer.strokeWeight(0.3);
  buffer.background(0);
  buffer.endDraw();
}

void resetPixelSampling(){
  for (int i=0; i < n; i++) {
    //cx[i] = i; // changed to a none random number for testing 
    //cy[i] = i; 
    cx[i] = random(img.width);
    cy[i] = random(img.height);
  }
}

void updatePixelSampling(){
  buffer.beginDraw();
  for (int i = 1; i < n; i++) {
    color c = img.get((int)cx[i], (int)cy[i]);
    buffer.stroke(c);
    // remap/re-scale coordinates from sampled image to target buffer size
    float bufferX = map(cx[i],0,img.width,0,bufferWidth);
    float bufferY = map(cy[i],0,img.height,0,bufferHeight);
    buffer.point(bufferX,bufferY);
    // you can choose channels: red(c), blue(c), green(c), hue(c), saturation(c) or brightness(c)
    float channel = hue(c);
    cy[i]+=sin(map(channel,0,255,0,TWO_PI));
    cx[i]+=cos(map(channel,0,255,0,TWO_PI));
  }

  buffer.endDraw();
}

void draw() {
  if (frameCount>len) {
    frameCount=0;
    println("iteration: " + tick++);
    resetPixelSampling();
  }

  updatePixelSampling();

  if(tick == 30) {
    if(!imageAutoSaved){
      imageAutoSaved = true;
      saveImage();
    }
  }

  image(buffer,0,0,width,height);
}

void keyPressed() {
  saveImage();
}

void saveImage(){
  buffer.save(foldername + filename + "/res_" + sessionid + hex((int)random(0xffff),4)+"_"+filename+fileext);
  println("image saved");
}

脚本可以进一步优化。例如,采样(分析)和合成算法可以移植到GLSL片段着色器。请注意,9000x9000是一张无法在GPU上上传纹理的大图像,但是,可以使用较小的缓冲区作为瓷砖,可以一次将一个部分渲染到大图像中。

关于将处理代码移植到python中,以便在gimp-python脚本中使用它:

  • Gimp有一个“Ink”绘画工具,它的大小可以小于一个像素。
  • 如果选择了GimpPythonAPI,则允许设置此大小:pdb.gimp_context_set_ink_size(0.3)
  • 瘸子PythonAPI也有绘画功能