4. Repte 4. Moviments

4.2. Importar imatges

Fins ara hem creat dibuixos fets a partir de les formes que creem amb p5.js. Però amb p5.js podem importar imatges en format jpg o png i fer-les servir per a incloure-les als nostres programes, podent fer composicions més complexes.

Per a poder treballar amb imatges necessàriament haurem de treballar en línia, amb el servidor FTP de la UOC, atès que per seguretat els navegadors no permeten la càrrega d’arxius de manera local.

És per això que crearem una carpeta nova, a què direm img, on guardarem les imatges que fem servir.

Organitzant l’espai del servidor

Vegem quina serà l’estructura que hem de tenir al servidor:

Dins la carpeta js tindrem els dos arxius que ja teníem, el p5.min.js i l’sketch.js.

Dins la carpeta img, guardarem les imatges que venen com a exemple al llibre, disponibles per a baixar-les des d’http://p5js.org/learn/books/media.zip.

Per a poder fer servir una imatge, haurem de fer tres passos previs:

  1. Copiar la imatge a la carpeta on tenim el nostre codi.
  2. Crear una variable que emmagatzemi la imatge.
  3. Carregar la imatge amb la funció loadImage().

Com farem aquests tres passos?

El primer pas ja l’hem fet. Per a tenir els nostres fitxers ben organitzats, hem emmagatzemat les imatges en una carpeta que es diu img, però veurem que això no influeix a l’hora de fer els nostres programes.

El segon i el tercer passos els veurem en aquest exemple:

var img;   // Definim una variable per a emmagatzemar la imatge
function preload() {   // Afegim una nova funció que ens 
                       // carrega la imatge
  img = loadImage("img/lunar.jpg");
}
function setup() {
  createCanvas(480, 120);
}
function draw() {
  image(img, 0, 0); // Dibuixa la imatge
}

La funció preload() es fa servir per a carregar la imatge abans d’executar el codi. De fet, si existeix aquesta funció, la funció setup() no s’executarà fins que la funció preload() hagi finalitzat (i, per tant, que totes les imatges estiguin carregades).

El resultat, si executem aquest programa, serà aquest:

Podeu veure aquest exemple funcionant a https://cv.uoc.edu/~ccasadom/PDA/html.

Aquest exemple es correspon amb l’exemple 7-1 del llibre (atenció al canvi que s’ha fet al codi –en color rosa– especificant el directori on hi ha la imatge emmagatzemada).

Per a dibuixar la imatge, hem fet servir la funció image() que té aquesta sintaxi:

image(img, x, y, [width], [height])

image(img, dx, dy, dWidth, dHeight, sx, sy, [sWidth], [sHeight])

La primera és fàcil, x i y indiquen la posició del canvas on es posarà la imatge (correspon amb la cantonada superior esquerra de la imatge) i width i height l’amplada i l’alçada. Si no indiquem aquestes dues dades, aleshores farà servir les mides originals.

La segona és més complexa, dx i dy indiquen la posició de la imatge al canvas, dWidth i dHeight la mida de la imatge al canvas, sx i sy a partir de quina posició mostrarem la imatge i sWitdth i sHeight la mida que agafarem de la imatge. Si sWitdth i sHeight són més petits que dWidth i dHeight, el tros d’imatge que es mostri es farà més gran i, en cas contrari, més petit.

En l’exemple 7-2 es fan dues coses. Per una banda, es carreguen dues imatges. Per l’altra, a l’hora de dibuixar-les es fan servir diferents efectes:

image(img1, -120, 0);

Això fa que la imatge que es carrega ho faci 120 píxels fora del canvas. El resultat és aquest:

Hem retallat la imatge per l’esquerra.

Ara afegim un altre cop la mateixa imatge, però canviant la posició x (130 píxels a la dreta) i retallant-la (ens quedem només amb 240 píxels d’amplada i 120 d’alçada).

image(img1, -120, 0);
image(img1, 130, 0, 240, 120);

Aquest és el resultat:

En el primer cas, com que no hem indicat la mida, ha intentat posar tota la imatge i ha sortit la part que cabia al canvas. En el segon cas, hem indicat la mida on s’havia d’encabir la imatge i la imatge s’ha adaptat a la mida disponible.

Ara afegim la segona imatge:

image(img1, -120, 0);
image(img1, 130, 0, 240, 120);
image(img2, 300, 0, 240, 120);

I aquest és el resultat:

Fixeu-vos que les imatges es posen unes a sobre de les altres. La darrera a dibuixar-se és la que estarà més amunt.

Podeu veure aquest exemple funcionant a https://cv.uoc.edu/~ccasadom/PDA/r5e2.html.

En l’exemple 7-3, la mida de la imatge varia segons el moviment del ratolí:

image(img, 0, 0, mouseX * 2, mouseY * 2);

En aquest exemple es pot veure com la imatge s’adapta a la mida que hem donat a la funció image().

Podeu veure aquest exemple a l’adreça https://cv.uoc.edu/~ccasadom/PDA/r5e3.html.

En els exemples 7-4 i 7-5, el que tenim són dues imatges, una en format gif i l’altra en format png, que tenen transparència. El codi és el mateix en els dos casos, l’única cosa que canvia és la imatge. Podeu veure aquests dos exemples a les adreces següents:

Quan tenim imatges gif o png amb transparència, podem posar la imatge amb transparència a sobre de qualsevol dibuix (sia una altra imatge o un dibuix generat per nosaltres mitjançant codi) i als llocs on la imatge sigui transparent, es veurà la imatge que tenim a sota.

L’exemple 7-6 carrega una imatge en format svg. Es pot veure funcionant a l’adreça https://cv.uoc.edu/~ccasadom/PDA/r5e6.html.

Finalment, els exemples 7-7 i 7-8 estan fets per a explicar que cal carregar les imatges i esperar que es carreguin abans de mostrar-les. L’exemple 7-7 és una còpia de l’exemple 7-1, però en aquest cas no s’espera la càrrega de la imatge. En conseqüència, la imatge no apareix en pantalla perquè s’intenta pintar abans d’estar carregada. Hi ha una petita «trampa», ja que al setup() es fa una crida a la funció noLoop() per tal que la funció draw() no es repeteixi, de manera que només es farà un cop. Compte, podria ser que ens interessés un codi on draw() no es repetís, per tant, no es pot considerar una trampa de veritat.

Aquest exemple es pot veure funcionant a https://cv.uoc.edu/~ccasadom/PDA/r5e7.html.

L’exemple 7-8 proposa una altra solució a la qüestió de la càrrega de la imatge. El que es fa és afegir un nou paràmetre a la funció loadImage() on s’indica quina funció caldrà cridar un cop s’hagi acabat la càrrega de la imatge.

Aquest exemple es pot veure funcionant a https://cv.uoc.edu/~ccasadom/PDA/r5e8.html.