I programmeringsmiljøet processing er det forholdsvist enkelt at loade og manipulere billeder. Det er et sandkassemiljø baseret på java udviklet som undervisningsmiljø til studerende i kommunikation, kunst, design m.m. Den danske kunstner Mogens Jacobsen har skrevet en fin, dansk introduktion til miljøet.
Når man har styr på basal processing, kan man gå videre med nedenståen opgaver, hvor man trin for trin ændrer på og laver filtrer der manipulerer et billede. Start med at downloade og afprøve programmet, gå i gang med opgaverne en efter en og slip til sidst fantasien løs og lave dine helt egne, vilde billedfiltre!
The Nature of Code: Gratis, interaktiv bog målrettet niveauet efter basal programmering. Den introducer vektorer & objekter i processing og går derefter videre til emner som Fysiske love; Oscillation; Fraktaler m.m.
FYProcessing: Samling af særligt spændende projekter lavet i processing.
Funprogramming: Videoer der introducerer programmering i processing med fokus på det visuelle.
Javabog.dk: Klassisk introduktion til Java på dansk fra betingelser helt til flertrådet programmering… Kan også bruges i uddrag til javabaserede miljøer som Processing og Greenfoot…
Processing & Arduino: Bibliotek til programmering af arduino via processing
Opstart
Optimering af funktioners start
- Opret de to indbyggede funktioner void mouseClicked(){} og void mouseMoved(){}
- Klip forgreningen ud der starter filtre i draw, og kopier den ind i de to funktioner.
- Noter hvordan filteret støj ændrer sig - hvornår kører det nu?
- Skriv en forklaring på hvorfor det sker og hvorfor der er bedre end bare at lade dem kører i draw().
- Slet funktionerne i mouseMoved, hvor der ikke sker en ny beregning (nyt billede) når musen flyttes
PImage billed; int aktueltFilter = -1; void setup() { billed = loadImage("langbold2.jpg"); size(billed.width, billed.height+50); } void draw() { knap(0,"Stoej"); knap(1,"Pixelering"); knap(2,"Lys"); knap(3,"Motionblur"); if(aktueltFilter == 0){ stoej(); }else if(aktueltFilter == 1){ pixelering(); }else if(aktueltFilter == 2){ lys(); }else if(aktueltFilter == 3){ motionBlur(); }else{ image(billed, 0, 0); } }
Knapper
Tilpas knapperne
- Ændr på farve
- Ændre på størrelse
- Ændr på form
Tilføj knap/filter
- Gå ind i Draw og indsæt en fjerde ekstra knap, der hedder "Meget støj".
- Ændr herefter forgreningen lige nedenunder, så funktionen "megetStoej()"startes når aktueltFilter er 4.
- Lav nu en kopi af filteret Stoej() og indsæt det lige nedenunder.
- Ændr det navn til megetStoej() og ændr random fra 10 til 20.
For mange knapper/lidt bredde?
Sørg for at knapperne sættes i to eller flere rækker.
- Lav en betingelse så kun de første 5 knapper laves som før
- De næste knapper lægges eks. 20 ekstra til knapY
- Afprøv og du vil se at knapperne tegnes nedenfor
- Står knapperne forkert?
- Tegnes de for langt inde, så sørg for at trække fra variablen aktueltFilter
- Tegnes de udenfor skærmbilledets højde - så juster size() i Setup()
- Virker de nye knapper ikke?
- Har du husket at gange variablen nr på betingelsen i mousePressed()?
void knap(int nr, String tekst){ int knapBredde=70; int knapHoejde=20; int knapY=billed.height+10; fill(50); rect(nr * knapBredde+5, knapY, knapBredde, knapHoejde); fill(255); text(tekst, nr * knapBredde+10, knapY+15); if(mousePressed == true && nr * knapBredde < mouseX && mouseX < (nr+1) * knapBredde && knapY < mouseY && mouseY < knapY+knapHoejde) { aktueltFilter = nr; } }
Filtre: pixels placering
Støj
- Ændre mængden af støj
- Udvid så der også er støj iforhold til y-akse
- Lav støjniveau følge mus' position
- Håndter kanter: hvad skal der ske, hvis random() giver en positon uden for billedet?
Spejl
Indsæt pixels i modsatte rækkefølge i forhold til bredden
- Kopier koden for stoej.
- Giv den et nyt navn og tilføj knap i draw
- Ændr koden, så nyX sættes til billedets bredde - x
void stoej(){ for(int y = 0; y < billed.height; y = y + 1){ for(int x = 0; x < billed.width; x = x + 1){ int nyX = x + int(random(10)); color hentFarve = billed.get(nyX, y); set(x, y, hentFarve); } } }
- Sørg for at spejlingen kun sker når musen er over billedets midte
- Lav flip, hvor det er y-aksen der byttes om på.
- Kombiner spejl og flip, så der spejlvendes og/eller flippes efter musens position
Symmetrisk spejl
Som spejl men lad, den ene halvdel tegnes almindelig, mens den anden spejles…
Filtre: form
Pixelering
- Ændre graden af pixelering ved at gøre størrelsen større/mindre
- Lad graden af pixelering følge mus' position - divider ned, hvis det er for følsomt
- Håndter kanter: hvad skal der ske, hvis de ydereste pixels går ud over billedets størrelse?
- Lad bredde afhænge af mouseX og højde af mouseY
- Surprise - der tegnes kun, hvor musen har været over…
- Reel pixelering: udregn og vis gennemsnitte af farveværdierne i stedet for blot at forstørre den første pixel.
void pixelering(){ int stoerrelse = 10; for(int y = 0; y < billed.height; y = y + stoerrelse){ for(int x = 0; x < billed.width; x = x + stoerrelse){ fill(billed.get(x, y)); stroke(billed.get(x, y)); rect(x, y, stoerrelse, stoerrelse); } } }
Linier
- Kopier pixelering(), giv den et nyt navn og tilføj knap i draw()
- Slet x-forløkken
- Hent farve fra 0, y
- Tegn en linje i billedets bredde
Andre former
Kopier pixelering() og ændr den så der tegnes cirkler, trekanter… i stedet
Filtre: pixels farve
Justering af lys
- Lad lysniveau følge mus' position
- Animer dagens gang
Farvefiltre
Vis kun udvalgte farver fra et billede
- Kopier koden for lys.
- Giv den et nyt navn og tilføj knap i draw().
- Ændr koden, så der kun vises én af farvetonerne - sæt de andre til nul
- Farveblind - vis gennemsnittet af rød og grøn i rød og grøn—-
- Gråtonefilter - vis et gennemsnit af de tre farver
- Lav andre farvefiltre som sepia, tusmørke, solopgang… ved at gange de tre farvetoner med tal mellem 0 og 1
- Lav et filter der farvetoner efter mus position
void lys(){ float lys = 0.5; for(int y = 0;y < billed.height; y = y + 1){ for(int x = 0;x < billed.width; x = x + 1){ color hentFarve = billed.get(x, y); float nyRoed = red(hentFarve)*lys; float nyGroen = green(hentFarve)*lys; float nyBlaa = blue(hentFarve)*lys; color nyFarve = color(nyRoed, nyGroen, nyBlaa); set(x, y, nyFarve); } } }
Gennemsigtighed
Læg to billeder sammen og divider med 2
- Kopier koden for lys(), giv nyt navn og tilføj knap i draw
- Sørg for at der oprettes og loades et ekstra billede i setup
- Ændr koden for lys, så der hentes farve fra begge billeder
- Ændr koden, så farverne i de to billeder lægges sammen og divideres med 2
- Lav en WARP - glidende overgang mellem de to billeder - enten animeret eller efter mus' position
- Lav en funktion der kombinere en eller to af billedernes - hvad med rød fra et billede, grønt fra et andet og blåtfra et tredje?
Filtre: foldningsmatrix
Motionblur
Øg antallet af pixels der bruges til 5 - overvej hvad der skal hentes når filteret når til kanten af billedet
- Lav en variable antalPixels
- Opret de tre variabler til farver som før men sæt dem til 0 fra start.
- Lav en forløkke, der kører antalPixels gange
- I forløkken hentes farveværdien for x + antalPixels, og de tre farver tælles op med den aktuelle værdi
- Efter forløkken sættes nyFarve til de optalte farveværdier / antalPixels
- Den aktuelle pixel sættes til den ny farveværdi
- Lad variablen antalPixel afhænge af mouseX - juster evt. følsomhed ved at dividere ned
Lodret motionblur
- Kopier koden for motionBlur(), giv nyt navn og tilføj knap i draw().
- Ændr' koden til at arbejde på y istedet for x
Andre foldningsmatricer
Som motionBlur, kan de andre filtre beskrevet i foldningsmatricer implementeres
void motionBlur(){ for(int y = 0;y < billed.height; y = y + 1){ for(int x = 0;x < billed.width; x = x + 1){ color hentFarve = billed.get(x, y); color hentFarveV1 = billed.get(x-1, y); color hentFarveH1 = billed.get(x+1, y); float nyRoed = (red(hentFarve) + red(hentFarveV1) + red(hentFarveH1))/3; float nyGroen = (green(hentFarve) + green(hentFarveV1) + green(hentFarveH1))/3; float nyBlaa = (blue(hentFarve) + blue(hentFarveV1) + blue(hentFarveH1))/3; color nyFarve = color(nyRoed, nyGroen, nyBlaa); set(x, y, nyFarve); } } }
Optimering
Brug den indbyggede pixel-tabel - pixels[blurPixel] - til at optimere hastigheden med. Alt efter filter, billedstørrelse & computer øger det hastigheden med 20-40%. - Ved foldningsmatrix, skal du bruge billede.width til udregne, hvor de omkringstående pixels er.