/* -*- Scala -*- */ /* Cifratura colorata */ import java.io.File import java.awt.image.BufferedImage import java.awt.image._ import java.io._ import java.net.URL import javax.imageio._ /* La funzione salva il canvas in un file. */ def esportaCanvas(fileName: String, larghezza: Int, altezza: Int) { val image = stage.canvas.getCamera.toImage(larghezza, altezza, stage.myCanvas.getBackground) javax.imageio.ImageIO.write(image.asInstanceOf[java.awt.image.BufferedImage], "png", new File(fileName)) } /* La funzione carica un file dal disco. */ def caricaImmagine(fileName : String) : BufferedImage = { ImageIO.read(new File(fileName)); } /* La funzione accede all'immagine in memoria che corrisponde al canvas. */ def accediAdImmagineInMemoria() : BufferedImage = { val image = stage.canvas.getCamera.toImage(canvasBounds.getWidth.toInt, canvasBounds.getHeight.toInt, stage.myCanvas.getBackground) image.asInstanceOf[BufferedImage] } /* La funzione legge il colore di un pixel alle coordinate date. */ def prendiColoreAlPixel(image : BufferedImage, x: Int, y: Int): Color = { val rgb = image.getRGB(x, y) val valoreRosso = (rgb & 0x00ff0000) >> 16 val valoreVerde = (rgb & 0x0000ff00) >> 8 val valoreBlu = rgb & 0x000000ff new Color(valoreRosso, valoreVerde, valoreBlu) } /* Funzione per disegnare poligoni regolari */ def poligono(lati: Int, lato: Int, colore1: Color, colore2: Color) { val angolo = 360 / lati.toDouble colorePenna(colore1) coloreRiempimento(colore2) seVero(lati % 2 >= 0) { sinistra(90 - angolo); } ripeti(lati) { avanti(lato) destra(angolo) } } /* Il programma genera una immagine partendo da un testo e poi la rilegge riestraendo le lettere. */ pulisci() switchToDefault2Perspective() ritardo(10) invisibile() val X = -300 val Y = 150 def scriviAllaPosizione(testo: String, x: Double, y: Double, colore: Color) { val t = nuovaTartaruga(x, y) t.invisibile() t.colorePenna(colore) t.scrivi(testo) } /* Funzione per generare un quadrato con il colore di riempimento in base alla lettera. Il codice della lettera è immagazzinato nel canale rosso del colore, i rimanenti verde e blu sono casuali. */ def letteraInQuadrato(lettera: Char, lato: Int = 50, marca: Boolean = false) { val coloreVerde = numeroCasuale(255) val coloreBlu = numeroCasuale(255) val coloreRosso = lettera.toInt val colore = new Color(coloreRosso, coloreVerde, coloreBlu, 255) poligono(4, lato, colore, colore) if (marca) scriviAllaPosizione(lettera.toString, posizione.x + (lato / 2), posizione.y + (lato / 2), nero) } /* La funzione codifica un testo in una sequenza di quadrati colorati. */ def codifica(testo: String, inizioX: Int, inizioY: Int, colonne: Int = 10, larghezzaColonna: Int = 50) { saltaVerso(inizioX, inizioY) var colonna = 1 var riga = 0 ripetiPerOgniElementoDi(testo) { lettera => letteraInQuadrato(lettera, larghezzaColonna) colonna += 1 if (colonna > colonne) { colonna = 1 riga += 1 saltaVerso(inizioX, inizioY - larghezzaColonna * riga) } else { saltaVerso(posizione.x + larghezzaColonna, posizione.y) } } poligono(4, larghezzaColonna, nero, nero) } /* La funzione cerca di valutare l'inizio del testo cifrato in colori nel canvas */ def trovaInizio(immagine: BufferedImage): Point = { val larghezzaImmagine = canvasBounds.getWidth.toInt val saltoX = 10 val saltoY = 20 var x = 0 var y = 0 var colore = bianco ripetiFinché(colore == bianco) { colore = prendiColoreAlPixel(immagine, x, y) if (x >= larghezzaImmagine - saltoX) { y += saltoY x = 0 } else x += saltoX } Point(x, y) } /* La funzione rilegge l'immagine generata estraendo il testo. La larghezza della colonna deve essere variata per adattarla all'immagine, la password insomma. */ def rileggi(immagine: BufferedImage, startX: Int, startY: Int, larghezzaColonna: Int = 50): String = { val centroDellaColonna = larghezzaColonna - 2 val larghezzaImmagine = canvasBounds.getWidth.toInt var x = startX var y = startY var colore = bianco var testo = "" var colonna = 1 var riga = 1 ripetiFinché(colore != nero) { colore = prendiColoreAlPixel(immagine, x, y) if (colore != bianco) { testo += colore.getRed.toChar } if (x >= larghezzaImmagine - centroDellaColonna) { colonna = 1 riga += 1 x = startX y += larghezzaColonna } else { colonna += 1 x += larghezzaColonna } } testo } /* Invocazione delle funzioni */ val imageFileName = "./lettere_e_colori3.png" val testo = "Oggi esco a passeggio con la mia amica Gigia, ma poi andiamo al cinema insieme." scriviAllaPosizione("testo: " + testo, -400, -250, nero) codifica(testo, X, Y) esportaCanvas(imageFileName, canvasBounds.getWidth.toInt, canvasBounds.getHeight.toInt) val immagine = caricaImmagine(imageFileName) val inizio = trovaInizio(immagine) val testoRiletto = rileggi(immagine, inizio.x.toInt, inizio.y.toInt) scriviAllaPosizione("riletto: " + testoRiletto, -400, -270, rosso)