xxxxxxxxxx
388
/* Citation:
p5.glitch library v0.1.0 cc teddavis.org 2020 https://github.com/ffd8/p5.glitch
clmtrackr + p5 basic exmaple. Face Tracking example created by Kyle McDonald revised by Xin Xin, 2020 https://kylemcdonald.github.io/cv-examples/
Stock image gold fish from envato elements, created by 3DAnimals. License acquired for this project.
*/
let glitch;
let capture;
let w = 200, h = 300;
let filter;
let tracker;
let positions;
let eye;
let nose;
let mouth;
let brow;
let eyesnaps = [];
let nosesnaps = [];
let mouthsnaps = [];
let browsnaps = [];
let goldfish;
let backgroundImg;
let sceneNum = 0;
let allowButton;
let denyButton;
let cameraOn = false;
let firstScreen;
let stopCamera;
let savePhoto;
let takePhoto;
let saveConsent = false;
let previewImg;
function preload() {
goldfish = loadImage('assets/goldfish.gif');
firstScreen = loadImage('assets/firstscreen.png');
stopCamera = loadImage('assets/stop.png');
savePhoto = loadImage('assets/save.png');
takePhoto = loadImage('assets/takephoto.png');
previewImg = loadImage('assets/preview.jpg');
}
function setup() {
createCanvas(400, 600);
filter = createGraphics(width, height);
filter.pixelDensity(0.5);
imageMode(CENTER);
noStroke();
//Create Allow button - Camera Access
allowButton = createButton('ALLOW');
allowButton.position(125, 300);
allowButton.size(150, 50);
allowButton.mousePressed(allowAccess);
allowButton.style('font-size', '25px');
let col1 = color(56, 52, 52);
allowButton.style("color","#fff");
allowButton.style('background-color', col1);
//Create Deny button - Camera Access
denyButton = createButton('DENY');
denyButton.position(125, 375);
denyButton.size(150, 50);
denyButton.style('font-size', '25px');
let col2 = color(255);
denyButton.style("color","#000");
denyButton.style('background-color', col2);
denyButton.mousePressed(denyAccess);
//Create Yes button - Save Access
yesButton = createButton('YES');
yesButton.position(125, 300);
yesButton.size(150, 50);
yesButton.mousePressed(allowSave);
yesButton.style('font-size', '25px');
yesButton.style("color","#fff");
yesButton.style('background-color', col1);
//Create No button - Save Access
noButton = createButton('NO');
noButton.position(125, 375);
noButton.size(150, 50);
noButton.style('font-size', '25px');
noButton.style("color","#000");
noButton.style('background-color', col2);
noButton.mousePressed(denySave);
//Create main screen's buttons
saveButton = new SaveButton();
captureButton = new CaptureButton();
stopButton = new StopButton();
}
function draw() {
switchScene();
}
function allowAccess(){ //Allow access to camera
capture = createCapture(VIDEO); //Start running the camera
capture.size(w, h);
capture.hide();
glitch = new Glitch();
glitch.pixelate(1);
tracker = new clm.tracker(); //Create a new clmtrackr object
tracker.init(); //Initialize the object
tracker.start(capture.elt); //Start tracking the video element capture.elt
sceneNum = 3;
cameraOn = true;
allowButton.hide();
}
function denyAccess(){ //Deny access to camera
sceneNum+=3; //Jump to final screen
if (cameraOn == true) {
cameraOn = false;
capture.remove();
}
}
function cameraCapture() { //Apply effect to video captured by camera
/* Creating glitch effect */
//p5.glitch library v0.1.0 cc teddavis.org
if(frameCount % 3 === 0) {
if(!mouseIsPressed){
glitch.loadImage(capture);
}
var value1 = random(1);
var value2 = random(0.5);
glitch.limitBytes(map(value1, 0, height, 0, 1));
glitch.randomBytes(map(value2, 0, width, 0, 100));
glitch.buildImage();
}
/* Create pixelated effect */
filter.loadPixels(); //Shows pixels
for (let y = 0; y < height; y = y + 5) {
for (let x = 0; x < width; x++) {
let i = x*height + y;
filter.pixels[i] = x + 0.2; // R
filter.pixels[i+1] = random(255); // G
filter.pixels[i+2] = random(255); // B
filter.pixels[i+3] = x + y; // A
}
}
filter.updatePixels(); //Shows pixels
image(capture, 150, 50, 200, 400); //Loads video layer
image(filter, 100, 200, 500, 300); //Loads filter layer
image(glitch.image, 200, 400); //Loads glitch video layer
/* Cut out images */
//Face Tracking example created by Kyle McDonald revised by Xin Xin 2020
push();
blendMode(HARD_LIGHT);
let positions = tracker.getCurrentPosition(); //Updates the tracker with current positions
if (positions.length > 0) {
eye = capture.get(positions[27][0], positions[27][1], 200, 50);
eyesnaps.push(eye);
nose = capture.get(positions[62][0], positions[62][1], 90, 80);
nosesnaps.push(nose);
mouth = capture.get(positions[57][0], positions[57][1], 300, 50);
mouthsnaps.push(mouth);
brow = capture.get(positions[20][0], positions[20][1], 100, 70);
browsnaps.push(brow);
for (var i= 0; i < eyesnaps.length; i++) {
image(eyesnaps[i], positions[62][0], positions[62][1]);
image(nosesnaps[i], positions[7][0], positions[7][1]);
image(mouthsnaps[i], positions[4][0], positions[4][1]);
image(browsnaps[i], positions[11][0], positions[11][1]);
}
}
pop();
/* Overlaying gold fish image */
image(goldfish, 180, 300, 200, 300);
}
/*-----------------------------------------------------------------------------------------*/
//Change the screen
function switchScene() {
switch(sceneNum) {
case 0: //Screen 1
//Information about the program's purpose and use of users' data
background(245, 239, 238);
displayText("This experimental camera\nprogram was created for the\npurpose of learning p5.js.\n\nYou will need to allow the program\nto get access to your device's camera\nin order to experience it.\n\nYou can stop the camera at any time.\n\nThe program will not save your data nor capture\nyour data for commercial purposes\nnor send your data to a third party.", width/2, 150, 16);
displayText("Click anywhere to continue", width/2, 500, 13);
//Opening screen graphic
let opacity = 255;
if (millis() >= 0 && millis() < 2000) {
tint(255, opacity);
image(firstScreen, width/2, height/2);
}
if (millis() >= 3000 && millis() < 5000) {
opacity--;
}
//Hide buttons
allowButton.hide();
denyButton.hide();
yesButton.hide();
noButton.hide();
break;
case 1: //Screen 2 - Preview Image
background(245, 239, 238);
displayText("Here's a preview of an\nimage taken by this camera.", width/2, 110, 16);
displayText("Click anywhere to continue", width/2, 500, 13);
image(previewImg, width/2, height/2, 200, 300); //Preview image
break;
case 2: //Screen 3 - Ask for camera access
background(245, 239, 238);
displayText("Would you like to grant\nthis program permission to\nuse your device's camera?", width/2, 150, 16);
allowButton.show();
denyButton.show();
yesButton.hide();
noButton.hide();
break;
case 3: //Screen 4 - Ask for save access
background(245, 239, 238);
displayText("Would you like to save images\nfrom the camera to your computer?", width/2, 150, 16);
yesButton.show();
noButton.show();
break;
case 4: //Screen 5 - Main screen
background(245, 239, 238);
push();
blendMode(HARD_LIGHT);
cameraCapture();
pop();
if (saveConsent == true) {
captureButton.body();
}
saveButton.body();
stopButton.body();
allowButton.hide();
denyButton.hide();
yesButton.hide();
noButton.hide();
break;
case 5: //Screen 8 - End screen
image(firstScreen, width/2, height/2);
displayText("Press R to restart the program", width/2, 500, 13);
yesButton.hide();
noButton.hide();
allowButton.hide();
denyButton.hide();
}
}
/*-----------------------------------------------------------------------------------------*/
//Display Text
function displayText(response, x, y, size) {
push(); //Start center rectMode
//rectMode(CENTER);
imageMode(CENTER);
fill(54, 22, 45);
textFont('ROBOTO');
textAlign(CENTER);
textSize(size);
text(response, x, y);
pop(); //Stop center rectMode
}
/*-----------------------------------------------------------------------------------------*/
//Click to next screen
function mousePressed() {
//Let user click anywhere to continue through onboarding screens
if (sceneNum >= 0 && sceneNum < 2) {
sceneNum++;
}
//Respond to click on Save Photo button
if (sceneNum == 4 && mouseX < saveButton.x + saveButton.w/2 && mouseX > saveButton.x - saveButton.w/2 && mouseY < saveButton.y + saveButton.w/2 && mouseY > saveButton.y - saveButton.w/2){
sceneNum--; //Return to previous screen to ask for save consent
}
//Respond to click on Take Photo button
if (sceneNum == 4 && mouseX < captureButton.x + captureButton.w/2 && mouseX > captureButton.x - captureButton.w/2 && mouseY < captureButton.y + captureButton.w/2 && mouseY > captureButton.y - captureButton.w/2){
if (saveConsent == true) {
saveToDevice(); //Save to device is save consent is granted
}
}
//Respond to click on Stop Camera button
if (sceneNum >= 3 && sceneNum < 6 && mouseX < stopButton.x + stopButton.w/2 && mouseX > stopButton.x - stopButton.w/2 && mouseY < stopButton.y + stopButton.w/2 && mouseY > stopButton.y - stopButton.w/2){
sceneNum = 5;
if (cameraOn == true) { //Stop camera from running
cameraOn = false;
capture.remove();
}
}
}
/*-----------------------------------------------------------------------------------------*/
//Press R to restart program
function keyPressed() {
if (keyCode == 82 && sceneNum == 5) {
sceneNum-=5;
cameraOn = false;
saveConsent = false;
}
}
/*-----------------------------------------------------------------------------------------*/
//Buttons
class SaveButton { //Change save setting button
constructor() {
this.x = 59;
this.y = 545;
this.w = 40;
this.h = 40;
}
body() {
image(savePhoto, 59, 545, 40, 40);
displayText('Save Setting', 59, 582, 12);
}
}
class CaptureButton { //Take photo and download button
constructor() {
this.x = width/2;
this.y = 545;
this.w = 54;
this.h = 54;
}
body() {
image(takePhoto, width/2, 545, 54, 54);
displayText('Capture', width/2, 582, 12);
}
}
class StopButton { //Stop camera access button
constructor() {
this.x = 341;
this.y = 545;
this.w = 40;
this.h = 40;
}
body() {
image(stopCamera, 341, 545, 40, 40);
displayText('Stop Camera', 341, 582, 12);
}
}
/*-----------------------------------------------------------------------------------------*/
//Save image function
function saveToDevice() { //Save image to device
saveCanvas('myImage', 'jpg');
}
/*-----------------------------------------------------------------------------------------*/
//Turn save on and off
function allowSave() { //Allow program to save image to device and move on to main screen
if (saveConsent == false) {
saveConsent = true;
}
sceneNum++;
}
function denySave() { //Prevent program from saving image to device and move on to main screen
if (saveConsent == true) { //Stop save consent if it's true and move to main screen
saveConsent = false;
sceneNum++;
}
if (saveConsent == false) { //Let save consent stay false and move to main screen
sceneNum == 4;
}
}