If(){design}else{art} Processing, le livre

23 novembre 2020

Vérifier la présence de la caméra

Filed under: tips — jean-noël Lafargue @ 12 h 22 min

Lorsque l’on veut accéder à la webcam avec la librairie video et l’objet Capture, il n’est pas rare que rien ne fonctionne alors même que la caméra est présente et qu’elle fonctionne de manière satisfaisante avec tous les autres logiciels (mais attention, deux logiciels différents ne peuvent pas accéder à une même caméra en même temps !)
Le problème le plus courant est que la définition de la capture que vous voulez obtenir ne fait pas partie des définitions d’image disponibles pour la caméra. Souvent, le format 640×480 est disponible mais il peut tout à fait être absent de la liste des possibilités, notamment avec les webcams récentes, qui sont prévues pour des formats supérieurs.
Le modeste programme qui suit vous permet de connaître la liste de toutes les caméras accessibles par Processing :

import processing.video.*;

String[] cameras = Capture.list();
for(String c:cameras){
  println(c);
}

Il suffit de le lancer pour obtenir, dans la console, une liste de possibilités.
Le résultat sera parfois un simple nom, comme « Logitech HD Webcam C270 », et parfois, une liste signalant les formats disponibles (320×240 à 60 images par seconde, par ex.).
Vous pourrez alors adapter l’initialisation de la capture en conséquence, soit en saisissant le nom du modèle (écrit exactement pareil) :

new Capture(this, "Logitech HD Webcam C270");

Cette méthode (avec le nom exact) est particulièrement importante lorsque plusieurs caméras différents sont connectées au même ordinateur.
S’il n’y a qu’une caméra, on peut se contenter de proposer la définition d’image trouvée (en supposant, dans ce cas, qu’il existe un format 320 x 240 pixels dans la liste) :

new Capture(this, 320, 240);

Voici enfin un simple programme qui :
– importe la librairie vidéo
– déclare un objet Capture() et l’initialise
– adapte le format de la fenêtre à celui de la capture
– et qui lit l’image capturée (si disponible) et l’affiche :

import processing.video.*;
Capture cap;

void setup(){
  cap = new Capture(this, "Logitech HD Webcam C270");
  cap.start();
  surface.setSize(cap.width, cap.height);
}
void draw(){
  if(cap.available()){
    cap.read();
    image(cap,0,0);
  }
}

10 mai 2017

Créer un kaléidoscope

Filed under: tips — jean-noël Lafargue @ 12 h 32 min

La fonction qui suit répète une image quatre fois sur l’écran, avec un effet d’inversion qui permet donc de créer un kaléidoscope.
L’image d’origine est celle-ci :

void repeteLimage(PImage g){ 
  image(g,0,0); 
  pushMatrix();
  translate(width,0);
  scale(-1,1);
  image(g,0,0);
  popMatrix();
  pushMatrix();
  translate(width,height);
  scale(-1,-1);
  image(g,0,0);
  popMatrix();
  pushMatrix();
  translate(0,height);
  scale(1,-1);
  image(g,0,0);
  popMatrix(); 

}

L’image finalement obtenue à l’écran est celle-ci :

14 mars 2017

Ordonner les éléments d’un tableau au hasard

Filed under: tips — jean-noël Lafargue @ 18 h 49 min

Il est souvent intéressant de déterminer aléatoirement l’ordre des éléments d’un tableau.
La fonction qui suit permet très simplement d’obtenir ce résultat : on lui soumet un tableau, elle parcourt ses éléments un à un puis ajoute ces derniers à un nouveau tableau, à une position au hasard. Le type de tableau doit être indiqué, il faut donc remplacer le mot type par String, int, float, etc., selon le besoin :

type[] shuffle(type[] origine){
  type[] resultat = new type[0];
  for(type s:origine){
     int pos = floor(random(resultat.length+1));
     resultat = (type[]) splice(resultat, s, pos);
  }
  return resultat;
} 

Dans l’exemple qui suit, le type de tableau choisi est String[] (chaîne de caractère).
Nous créons un tableau contenant les valeurs « 1 », « 2 », « 3 », « 4 », « 5 », puis, à dix reprises, nous mélangeons ce tableau.

void setup(){
  size(1024,768);
  String[] s = {"A", "B", "C", "D", "E"};
  for(int a=0;a<10;a++){
    s = shuffle(s); println(s); 
  }
}
  
String[] shuffle(String[] origine){
  String[] resultat = new String[0];
  for(String s:origine){
     int pos = floor(random(resultat.length+1));
     resultat = (String[]) splice(resultat, s, pos);
  }
  return resultat;
}

Le résulstat sera (par exemple) :

D B E C A
A E B C D
B D E C A
A D C E B
B D C E A
A C D E B
D C E B A
A E C B D
E D C B A
D A C B E

8 mai 2014

Créer une animation GIF avec la librairie « gifAnimation »

Filed under: tips — jean-noël Lafargue @ 18 h 22 min

La librairie gifAnimation permet d’exporter un fichier au format GIF animé directement depuis Processing. Elle n’a malheureusement pas encore été portée sous Processing 3 et ne fonctionne donc qu’avec les versions précédentes.

La première étape est de télécharger la librairie gifAnimation.
Depuis la version 2 de Processing, cette opération peut se réaliser de manière assez automatique, depuis le menu « Sketch ».
On commence par aller dans « Import Library… » puis « Add Library… ».

 

import_librairie

 

…ce qui fait apparaître la fenêtre du gestionnaire des librairies, le « Library manager », où figurent les nom des librairies installées et de celles qui sont disponibles.
Pour télécharger une librairie, on clique simplement sur le bouton « Install ». La suite se déroule automatiquement.
Bien évidemment, votre ordinateur doit être connecté à Internet pour que ce téléchargement fonctionne.

 

import_librairie2

 

Une fois installée, la librairie est immédiatement disponible.
L’étape suivante, dans notre programme, sera de déclarer la librairie, et de déclarer un objet GifMaker, que nous choisirons de nommer gifExport :

 

import gifAnimation.*;
GifMaker gifExport ;

 

Cet objet sera plus tard instancié dans la section setup :

 

gifExport = new GifMaker(this, "monjoligifanime.gif"); // on instancie l'objet et on indique le nom qu'aura le fichier
gifExport.setRepeat(0); // on déclare le nombre de répétitions de la boucle (0 : infini)        
gifExport.setTransparent(255,255,255); // on déclare la couleur de transparence (ici, du blanc)

 

Au cours de l’animation, chaque fois que nous désirerons enregistrer le contenu de notre fenêtre en tant que « frame » (photogramme) de notre animation, nous utiliserons les commandes setDelay() (pour définir la durée de l’image, en millisecondes), et addFrame(), pour enregistrer :

 

gifExport.setDelay(20);
gifExport.addFrame();

 

Enfin, lorsque toutes les images que nous souhaitons enregistrer l’auront été, nous pourrons arrêter l’animation et procéder à l’enregistrement :

 

gifExport.finish();  
noLoop();

 

Voici le programme complet, qui dessine un rectangle en train de grandir. Chaque étape est enregistrée, et lorsque le rectangle dépasse le format de notre fenêtre, l’animation s’interrompt et le gif animé est enregistré.

 

import gifAnimation.*;
GifMaker gifExport ;
float taille=0;

void setup() {
size(200,200); 
    gifExport = new GifMaker(this, "monjoligifanime.gif");
    gifExport.setRepeat(0);             
   gifExport.setTransparent(255,255,255);  
    noFill();
    strokeWeight(10);
    rectMode(CENTER);
}

void draw() {
    background(255);
    rect(width/2, height/2, taille, taille);
    taille+=2;
    taille*=1.2;
    
    gifExport.setDelay(20);
    gifExport.addFrame();
    if(taille>width){ 
    gifExport.finish();  
      noLoop();
    }
}

 

Une fois le Gif fabriqué, vous n’aurez plus qu’à aller le récupérer à l’intérieur de votre « Sketch folder », avec la commande « Sketch -> show sketch folder ».
Attention les yeux, voici le résultat :

 

monjoligifanime

 

16 février 2013

Faire la liste des fichiers d’un dossier

Filed under: tips — jean-noël Lafargue @ 21 h 10 min

Le programme qui suit permet de faire la liste des fichiers qui se trouvent dans un dossier sélectionné par l’utilisateur.
Cette version est réservée à Processing 2.0 et plus pour deux raisons :
– la librairie « File » n’est plus chargée par défaut, il faut donc l’importer au début du programme. File est une librairie complète d’accès aux fichiers.
– la fonction selectFolder() ne s’utilise plus sans arguments, il faut désormais spécifier un texte à afficher et le nom de la fonction qui est appelée pour traiter le résultat.

// version pour processing 2.07

import java.io.File; // librairie java permettant de manipuler l'objet File dans processing 2 et +
String[] ListeFichiers; // la liste des fichiers
String[] types = {".jpg", ".jpeg", ".png"}; // les types de fichiers qui seront listés

void setup(){
size(800, 600);
}

void draw(){
// fonction à créer lorsque l'on veut utiliser les touches du clavier
}

void keyReleased(){
if(key=='o'){
// Si on clique sur la touche 'o', processing ouvre une boite de dialogue
// pour sélectionner un dossier
// puis le transmet à la fonction nommée "ObtiensLeContenuDuDossier"
selectFolder("choisissez un dossier", "ObtiensLeContenuDuDossier");
}
}

void ObtiensLeContenuDuDossier(File f){
// fonction qui traite
File[] ff = f.listFiles();
ListeFichiers = new String[0];
for(File fff:ff){
String n = fff.getAbsolutePath();
boolean isok = false;
for(String type:types){
// on vérifier que le fichier appartient à un type autorisé
String[] m = match(n, type+"\\Z");
if(m != null){
isok=true;break;
}
}
if(isok){
ListeFichiers = (String[]) append (ListeFichiers, n);
}
}
println(ListeFichiers);
}

Ici, le programme se déclenche lorsque l’on appuie sur la touche « o ». La liste « ListeFichiers » est alors remplie avec tous les chemins absolus vers les fichiers qui ont les terminaisons choisies (ici : jpg, jpeg et png).
Le résultat est ensuite montré à l’aide de la commande println.
Ce programme ne fonctionne pas en mode Javascript.

19 décembre 2012

Parcourir simplement les éléments d’un tableau

Filed under: tips — jean-noël Lafargue @ 7 h 43 min

Le principe n’est pas très bien documenté, mais Processing permet d’effectuer une itération (boucle) pour parcourir un a un les éléments d’un tableau (ou liste).
La méthode est très simple : on emploie la formule for (type élément : tableau){ … }type est le type de la variable, où élément sera le nom donné à chaque élément du tableau et où tableau est le tableau d’éléments en question. Dans l’exemple qui suit, nous créons un tableau de type « entier » nommé chiffres (au pluriel) qui contient les éléments : 1, 12, 14, 32 et 80.

int[] chiffres = {1,12,14,32,80};

Dans les lignes qui suivent, nous parcourons un à un les éléments de ce tableau, qui prennent chaque fois le nom chiffre (au singulier), et nous les affichons dans la zone de dialogue de Processing, à l’aide de la commande « println() ».

for(int chiffre : chiffres){
println(chiffre);
}

Cette méthode est un peu plus facile à comprendre et à manipuler que celle-ci :

for(int a=0;a<chiffres.length;a++){
int chiffre = chiffres[a];
println(chiffre);
}

1 juillet 2012

Savoir si plusieurs touches sont pressées simultanément

Filed under: tips — jean-noël Lafargue @ 13 h 46 min

Pour les besoins d’un jeu, par exemple, on peut avoir besoin de tester si plusieurs touches du clavier sont pressées en même temps, mais Processing ne le permet pas directement et ses variables key (caractère de la touche enfoncée) et keyCode (code numérique de la touche enfoncée) ne conservent qu’une seule référence, la dernière.

L’astuce qui suit consiste à créer un tableau booléen (une énumération de valeurs qui sont soit true soit false) dont les valeurs sont changées à chaque keyPressed() et keyReleased(), c’est à dire lorsque l’on appuie sur une touche et lorsqu’on lâche une touche. Ce tableau a une longueur de 128 éléments, ce qui doit suffire à traiter tous les cas puisque le codage de caractères ASCII contient 128 caractères.
Pour vérifier si un caractère est enfoncé, on utilise la fonction « verifieClavier(n) » où n sera soit un caractère (‘a’, ‘z’), soit un code (10 pour la touche Return, 32 pour la touche espace, etc.). La fonction renverra true ou false, selon le cas.


boolean[] touches=new boolean[128];

void draw(){
background(0);
text(" a : "+verifieClavier('a')+"\n b : "+verifieClavier('b')+"\n return : "+verifieClavier(10)+"\n espace : "+verifieClavier(32), 10, 10);
}

void keyPressed(){
touches[keyCode]=true;
}

void keyReleased(){
touches[keyCode]=false;
}

boolean verifieClavier(char c){
int cc = int(c);
if(cc>96 && cc<123)cc-=32;
return touches[cc];
}

boolean verifieClavier(int c){
return touches[c];
}

On peut imaginer beaucoup de variantes à ces fonctions.
On remarquera qu’il existe deux verifieClavier(),  l’un pour traiter les chiffres (ex. : verifieClavier(32) pour savoir si la touche « espace » est enfoncée) et l’autre pour traiter les caractères (verifieClavier(‘a’)).
La seconde version fait une petite conversion afin qu’il n’y ait pas de différence entre minuscules et majuscules : A et a sont traitées comme une seule et même lettre.

18 juin 2011

Pour utiliser plusieurs programmes successivement

Filed under: tips — jean-noël Lafargue @ 11 h 19 min

Suite à la demande d’un lecteur, voici une méthode très simple pour passer d’un programme à un autre.
En réalité, il n’y a qu’une seule animation, mais notre fonction « draw() » s’exécute différemment selon l’état de la variable sketchEnCours. Si cette variable a la valeur 1, c’est le programme draw_1() qui est exécuté, et si c’est elle a la valeur 2, c’est le programme draw_2() qui le sera.
On passe du mode 1 au mode 2 en appuyant sur les touches « 1 » et « 2 ».

int sketchEnCours = 1;
void setup(){
size(500,500);
background(0);
}

void draw(){
if(sketchEnCours==1){
draw_1();
}
if(sketchEnCours==2){
draw_2();
}
}

void draw_1(){
stroke(255);  float an=random(TWO_PI);float r=random(200); 
line(width/2, height/2, width/2+cos(an)*r, height/2+sin(an)*r);
}

void draw_2(){
stroke(0);  rect(random(width),random(height),10,10);
}

void keyPressed(){
if(key=='1'){    background(0);    sketchEnCours=1;  }
if(key=='2'){    background(255);    sketchEnCours=2;}
}

Si les différentes sous-animations sont complexes, réclament des variables spécifiques, etc., on gagnera à traiter tout cela en programmation objet.

Powered by WordPress