Sto eseguendo alcune manipolazioni di immagini in Scala facendo uso di oggetti BufferedImages e Raster. Sto cercando di ottenere tutti i pixel nell'immagine bufferizzata con il seguente codice.
val raster = f.getRaster()
// Preallocating the array causes ArrayIndexOutOfBoundsException .. http://forums.sun.com/thread.jspa?threadID=5297789
// RGB channels;
val pixelBuffer = new Array[Int](width*height*3)
val pixels = raster.getPixels(0,0,width,height,pixelBuffer)
Ora, quando leggo in file relativamente grandi, questo funziona correttamente. Quando ho letto in 20x20 file PNG, ottengo un ArrayIndexOutOfBoundsException:
java.lang.ArrayIndexOutOfBoundsException: 1200
at sun.awt.image.ByteInterleavedRaster.getPixels(ByteInterleavedRaster.java:1050)
Ho letto online che il modo per aggirare questo problema è quello di non preallocare il pixelBuffer, ma invece di passare a un valore nullo e uso quello restituito dal metodo Raster.getPixels.
Ecco il mio problema. Quando faccio l'approccio ingenuo e basta passare Nil come ultimo argomento:
val pixels = raster.getPixels(0,0,width,height,Nil)
ottengo l'errore
error: overloaded method value getPixels with alternatives (Int,Int,Int,Int,Array[Double])Array[Double] <and> (Int,Int,Int,Int,Array[Float])Array[Float] <and> (Int,Int,Int,Int,Array[Int])Array[Int] cannot be applied to (Int,Int,Int,Int,Nil.type)
val pixels = raster.getPixels(0,0,width,height,Nil)
Così, ovviamente, il compilatore non può determinare quale dei due metodi che sto cercando di chiamare ; è ambiguo. Se stavo usando Java, avrei lanciato il null per rendere esplicito il mio intento. Non riesco a capire come ottenere lo stesso effetto in Scala. Le cose che ho provato:
val pixelBuffer:Array[Int] = Nil // Cannot instantiate an Array to Nil for some reason
Nil.asInstanceOf(Array[Int]) // asInstanceOf is not a member of Nil
Qualsiasi idea di come dire al compilatore esplicitamente che voglio il metodo con l'array Int come ultimo parametro piuttosto che un array di float?
EDIT: Come risposta precisa, mi è stato sempre Nil mescolato con null. Nil è una lista vuota. Vedere il seguente blog post
Inoltre, dovrei sottolineare che l'eccezione di array fuori limite è stata colpa mia (come spesso accade). Il problema era che stavo dando per scontato che il raster avesse 3 canali, ma la mia immagine aveva 4 canali, dato che l'avevo creata in quel modo. Io invece preallocare l'array come segue:
val numChannels = raster.getNumBands()
val pixelBuffer = new Array[Int](width*height*numChannels)
val pixels = raster.getPixels(minX,minY,width,height,pixelBuffer)
Grazie per l'aiuto
Questa è una spiegazione perfetta. Grazie – I82Much
Preferirei che ha spiegato che attribuendo significa chosing quale dei possibili tipi che si desidera un valore di assumere, mentre lancia costringe un valore in un altro tipo, che può o non può prendere. –