Размытые края продолжают восстанавливать непрозрачность 100% (Обработка) - PullRequest
3 голосов
/ 03 октября 2019

Я пытаюсь создать круглую кисть с размытыми краями при обработке с помощью следующего кода. Форма круга рисуется попиксельно, потому что в реальной версии я пытаюсь рисовать пикселями, взятыми из PGraphic pg.

PFont font;
PGraphics pg;
int X;
int Y;
int rad = 20;

void setup (){
    size(800, 800, P2D);
    background(0);
    noStroke();

    pg = createGraphics(800, 800, JAVA2D);
    pg.beginDraw();
    pg.fill(255);
    pg.noStroke();
    pg.textFont(font);
    pg.textSize(400);
    pg.pushMatrix();
    pg.translate(width/2, height/2-140);
    pg.textAlign(CENTER, CENTER);
    pg.text("b", 0 , 0);
    pg.popMatrix();
    pg.endDraw();
}

void draw () {
    image(pg,0,0);
}

void mousePressed(){
    X = mouseX;
    Y = mouseY;
}

void mouseDragged(){

    for (int x=0; x<rad; x++) {
        for (int y=0; y<rad; y++) {
        float distance = sqrt(pow(x,2)+pow(y,2));
        float alpha = 255-map(distance,0,rad,0,255);

            if (sqrt(pow(x,2)+pow(y,2)) < rad){
                pg.beginDraw();
                pg.set(mouseX+x,mouseY+y,color(255,255,255, alpha));
                pg.set(mouseX-x,mouseY+y,color(255,255,255, alpha));
                pg.set(mouseX+x,mouseY-y,color(255,255,255, alpha));
                pg.set(mouseX-x,mouseY-y,color(255,255,255, alpha));
                pg.endDraw();
            }
        }
    }
}

Ответы [ 2 ]

1 голос
/ 03 октября 2019

Создайте функцию, которая рисует одну точку на PGraphics объекте:

void DrawPen(PGraphics pg, int cptX, int cptY, int r) {
    pg.beginDraw();
    for (int x = 0; x < r; ++x) {
        for (int y = 0; y < r; ++y) {
          float distance = sqrt(x*x + y*y);
          float alpha = 255-map(distance,0,r,0,255);
          if (distance < r) {
              pg.set(cptX+x,cptY+y,color(255,255,255, alpha));
              pg.set(cptX-x,cptY+y,color(255,255,255, alpha));
              pg.set(cptX+x,cptY-y,color(255,255,255, alpha));
              pg.set(cptX-x,cptY-y,color(255,255,255, alpha));
          }
        }
    }
    pg.endDraw();
}

Нарисуйте точку на отдельном PGraphics объекте в setup

PGraphics pg;
PGraphics pg_pen;
int rad = 20;

void setup (){
    size(800, 800, P2D);

    pg = createGraphics(800, 800, JAVA2D);
    pg.beginDraw();
    // [...]
    pg.endDraw();

    pg_pen = createGraphics(2*rad, 2*rad, JAVA2D);
    DrawPen(pg_pen, rad, rad, rad);
}

Когда мышь перетаскивают, смешайте pg_pen с общим PGraphics объектом (pg) в текущей позиции мыши:

void mouseDragged(){
    pg.beginDraw();
    pg.image(pg_pen, mouseX-rad, mouseY-rad);
    pg.endDraw();
}

Для поиска полноты функция draw:

void draw () {
    background(0); 
    image(pg,0,0);
}


[...] и попытался получить цвет из белой части для рисования на черной части.

Добавьте параметр color к функции DrawPen и очистите перо PGraphics, прежде чем рисовать на нем:

void DrawPen(PGraphics pg, int cptX, int cptY, int r, color c) {
    pg.beginDraw();
    pg.clear();
    for (int x = 0; x < r; ++x) {
        for (int y = 0; y < r; ++y) {
          float distance = sqrt(x*x + y*y);
          float alpha = 255-map(distance,0,r,0,255);
          if (distance < r) {
              color pc = color(red(c),green(c),blue(c), alpha);
              pg.set(cptX+x,cptY+y,pc);
              pg.set(cptX-x,cptY+y,pc);
              pg.set(cptX+x,cptY-y,pc);
              pg.set(cptX-x,cptY-y,pc);
          }
        }
    }
    pg.endDraw();
}

Получить цвет при нажатии мышиперезвоните событие и измените цвет пера:

void mousePressed() {
    color c = pg.get(mouseX, mouseY);
    println(c);

    DrawPen(pg_pen, rad, rad, rad, c);
}

Обратите внимание, что цвет получается от объекта pg, а не отэкран. Если вы хотите получить цвет с экрана, тогда оно должно быть (без .pg):

color c = get(mouseX, mouseY);

Далее цвет меняется в любое время, когда нажата какая-либо мышь (нажата не перетаскивается). Возможно, вы хотите изменить цвет при нажатии правой кнопки мыши и рисовать при нажатии левой кнопки мыши:

void mousePressed() {
    if (mouseButton == RIGHT) {
        color c = pg.get(mouseX, mouseY);
        println(c);
        DrawPen(pg_pen, rad, rad, rad, c);
    }
}
1 голос
/ 03 октября 2019

добавить «background (0);»перед "изображение (pg, 0,0);"в вашем методе рисования, таким образом, вы каждый раз сбрасываете фон, если вы этого не сделаете, программа будет продолжать рисовать изображения каждого кадра поверх друг друга, что приведет к медленному увеличению непрозрачности пикселей с низкой непрозрачностью каждый кадр до достижения 100%

void draw () {
  background(0);
  image(pg,0,0);
}

Редактировать: После тестирования вашего кода я заметил, что была проблема с тем, как вы создавали эти круги, из-за чего он работал очень медленно (каждый кадр, который вы проходите через этот двойник, чтобы нарисовать один цикл)круг), а также дал эту странную проблему с черными краями, вот что я сделал:

Сначала я использовал вашу переменную pg и нарисовал на ней один круг при запуске, затем я объявил еще одну PGraphics 'pg_all', гдеЯ рисовал одну строчку при каждом вызове метода mousedrag, я тестировал его на нескольких фонах, похоже, что он работает нормально, вот окончательный код, дайте мне знать, если вы не поняли часть или хотите сделать это по-другому:

PFont font;
PGraphics pg;
PGraphics pg_all;
int X;
int Y;
int rad = 20;

void setup (){
  size(800, 800, P2D);
  background(0);
  noStroke();

  pg_all = createGraphics(800, 800, JAVA2D);
  pg_all.beginDraw();
  pg_all.endDraw();

  pg = createGraphics(800, 800, JAVA2D);
  pg.beginDraw();
  for (int x=0; x<rad; x++) {
    for (int y=0; y<rad; y++) {
      float distance = sqrt(pow(x,2)+pow(y,2));
      float alpha = 255-map(distance,0,rad,0,255);

      if (sqrt(pow(x,2)+pow(y,2)) < rad){
        pg.beginDraw();
        pg.set(20+x,20+y,color(255,255,255, alpha));
        pg.set(20-x,20+y,color(255,255,255, alpha));
        pg.set(20+x,20-y,color(255,255,255, alpha));
        pg.set(20-x,20-y,color(255,255,255, alpha));
        pg.endDraw();
      }
    }
  }
  pg.endDraw();
}

void draw () {   
  background(0);
  image(pg_all,0,0); 
}

void mouseDragged(){
  X = mouseX;
  Y = mouseY;

  pg_all.beginDraw();
  pg_all.image(pg,X-rad,Y-rad);
  pg_all.endDraw();
}
...