Выбор области с веб-камеры для скриншота и захвата в p5js не работает

#javascript #p5.js

Вопрос:

Я хотел сделать снимок экрана из выбранной области камеры, когда я нажимаю кнопку «Добавить снимок экрана», но ничего не появляется, кроме пустого холста, также другая кнопка «Добавить захват» добавит еще один холст, чтобы продолжать захватывать выбранную область камеры, когда я нажимаю ее, но также ничего не появляется, кроме пустого холста. Интересно, что на самом деле происходит, когда я нажимаю на кнопку? ссылка на скрипт в редакторе p5js

 let video;
let shots = [];
let captures = [];
let button1;
let button2;
let canvas1, canvas2;
let lastmouseX = 0, lastmouseY = 0;
let firstmouseX = 0, firstmouseY = 0;

const s1 = p => {
  p.setup = () => {
    console.log("asd");
    // video
    video = p.createCapture(p.VIDEO);
    video.hide();
    // canvas
    canvas1 = p.createCanvas(700, 500);
    canvas2 = p.createGraphics(700, 500);
    // button1
    button1 = p.createButton("Add screenshot");
    button1.size(200, 100);
    button1.mousePressed(() => {
      shots.push(new p5(s2, "screenshotbox"));
    });
    // button2
    button2 = p.createButton("Add Capture");
    button2.size(200, 100);
    button2.mousePressed(() => {
      captures.push(new p5(s3, "capturebox"));
    });
  };
  p.draw = () => {
    canvas2.clear();
    p.image(video.get(), 0, 0, 700, 500);
    canvas2.fill(175, 100);
    canvas2.rect(firstmouseX, firstmouseY, lastmouseX-firstmouseX, lastmouseY-firstmouseY);
    if (p.mouseIsPressed) {
      canvas2.clear();
      if (!(p.mouseX > 710 || p.mouseX < -10 || p.mouseY < -10 || p.mouseY > 510)) {
        canvas2.rect(firstmouseX, firstmouseY, p.mouseX-firstmouseX, p.mouseY-firstmouseY);
      }
      else {
        canvas2.rect(firstmouseX, firstmouseY, lastmouseX-firstmouseX, lastmouseY-firstmouseY);
      }
    }
    p.image(canvas2, 0, 0);
  };
  p.mousePressed = () => {
      if (!(p.mouseX > 710 || p.mouseX < -10 || p.mouseY < -10 || p.mouseY > 510)) {
        (p.mouseX > 700) ?
          firstmouseX = 700 :
          (p.mouseX < 0) ?
            firstmouseX = 0 :  
            firstmouseX = p.mouseX;
        (p.mouseY > 500) ?
          firstmouseY = 500 :
          (p.mouseY < 0) ?
            firstmouseY = 0 :  
            firstmouseY = p.mouseY;
      }
      // console.log("r", p.mouseX, p.mouseY);
      // console.log("nr", firstmouseX, firstmouseY);
    };
    p.mouseReleased = () => {
      if (!(p.mouseX > 710 || p.mouseX < -10 || p.mouseY < -10 || p.mouseY > 510)) {
        (p.mouseX > 700) ?
          lastmouseX = 700 :
          (p.mouseX < 0) ?
            lastmouseX = 0 :  
            lastmouseX = p.mouseX;
        (p.mouseY > 500) ?
          lastmouseY = 500 :
          (p.mouseY < 0) ?
            lastmouseY = 0 :  
            lastmouseY = p.mouseY;
      }
      // console.log("r", p.mouseX, p.mouseY);
      // console.log("nr", lastmouseX, lastmouseY);
    };
}

new p5(s1, "scripts");

const s2 = p => {
  p.setup = () => {
    let w = lastmouseX-firstmouseX;
    let h = lastmouseY-firstmouseY;
    p.createCanvas(150, 150);
    p.image(video.get(firstmouseX, firstmouseY, w, h), 0, 0, 150, 150);
  };
};

const s3 = p => {
  let w, h;
  let fx, fy;
  p.setup = () => {
    w = lastmouseX-firstmouseX;
    h = lastmouseY-firstmouseY;
    fx = firstmouseX;
    fy = firstmouseY;
    p.createCanvas(150, 150);
  };
  p.draw = () => {
    p.image(video.get(fx, fy, w, h), 0, 0, 150, 150);
  };
};
 

Комментарии:

1. Похоже, работает в хроме 93. Какой браузер вы используете?

2. @PaulWheeler Я использую Microsoft Edge, но я тоже пробовал это в Google Chrome, и это все еще не работает, когда я нажимаю кнопку во второй раз, это не сработает, вы пробуете это в ссылке редактора p5js?

3. Да, с помощью редактора p5js. Я периодически вижу проблему, когда, если я сначала нажму снимок экрана, а затем сделаю снимок, я получу проблему с пустым холстом. Но если я обновлю страницу и повторю попытку, это сработает.

4. Здорово, что вы делитесь кодом и объясняете, чего вы пытаетесь достичь. Меня немного смущает необходимость 3 отдельных p5.js наброски. Кнопка захвата предназначена для короткого захвата видео ? Интересно, можно ли упростить функциональность скриншота (например, один эскиз, который захватывает копию PImage выбора/области интересов и добавляет элемент <canvas /> на страницу).

5. К сожалению, я не могу заставить проблему воспроизводиться достаточно последовательно для диагностики. Однако я обнаружил, что ваш код работает только в том случае, если вы создадите область выбора, щелкнув и перетащив ее вниз и вправо (я подробно расскажу об этой проблеме в ответе).

Ответ №1:

Одна из возможных проблем, с которой вы сталкиваетесь, заключается в том, что если положение мыши при отпускании кнопки мыши имеет значение x или y меньше, чем положение мыши при нажатии кнопки, то вы получите отрицательную ширину или высоту для части изображения, которое вы рисуете, что не сработает. Вот простое решение:

 const s2 = p => {
  p.setup = () => {
    let w = p.abs(lastmouseX-firstmouseX);
    let h = p.abs(lastmouseY-firstmouseY);
    p.createCanvas(150, 150);
    p.image(video.get(p.min(firstmouseX, lastmouseX), p.min(firstmouseY, lastmouseY), w, h), 0, 0, w, h);
  };
};

const s3 = p => {
  let w, h;
  let fx, fy;
  p.setup = () => {
    w = p.abs(lastmouseX-firstmouseX);
    h = p.abs(lastmouseY-firstmouseY);
    fx = p.min(firstmouseX, lastmouseX);
    fy = p.min(firstmouseY, lastmouseY);
    p.createCanvas(150, 150);
  };
  p.draw = () => {
    p.image(video.get(fx, fy, w, h), 0, 0, w, h);
  };
};
 

При вычислении ширины и высоты выбранной области мы используем абсолютное значение разницы, а при нахождении левой и верхней координат мы используем меньшее из двух значений x или y соответственно.

https://editor.p5js.org/Kumu-Paul/sketches/DrKz9rYbp