Estoy haciendo algo de manipulación de imágenes en Scala haciendo uso de imágenes BufferedImages y objetos Raster. Estoy intentando obtener todos los píxeles en la imagen almacenada en el búfer con el siguiente código.
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)
Ahora, cuando leo en archivos relativamente grandes, esto funciona bien. Cuando leí en 20x20 archivos PNG, consigo un ArrayIndexOutOfBoundsException:
java.lang.ArrayIndexOutOfBoundsException: 1200
at sun.awt.image.ByteInterleavedRaster.getPixels(ByteInterleavedRaster.java:1050)
He leído online que la forma de evitar este problema es no asignar previamente la pixelBuffer, pero en lugar de pasar de un valor nulo y el uso de la devuelto por el método Raster.getPixels.
Aquí está mi problema. Cuando hago el enfoque ingenuo y sólo tiene que pasar Cero como último argumento:
val pixels = raster.getPixels(0,0,width,height,Nil)
consigo el error
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)
Así que, obviamente, el compilador no puede determinar cuál de los dos métodos que estoy tratando de llamar ; es ambiguo Si estuviera usando Java, lanzaría el nulo para que mi intención sea explícita. No puedo entender cómo obtener el mismo efecto en Scala. Cosas que he intentado:
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
alguna idea de cómo decirle al compilador explícitamente que quiero que el método de la matriz Int como último parámetro en lugar de una red de flotadores?
EDITAR: Como una respuesta señala, Nil estaba confundido con nulo. Nil es una lista vacía. Consulte el siguiente blog post
Además, debo señalar que la excepción fuera de límites de la matriz fue mi culpa (ya que estas cosas a menudo lo son). El problema fue que asumí que el ráster tenía 3 canales, pero mi imagen tenía 4 canales, ya que lo había creado de esa manera. Yo en cambio asignar previamente la matriz de la siguiente manera:
val numChannels = raster.getNumBands()
val pixelBuffer = new Array[Int](width*height*numChannels)
val pixels = raster.getPixels(minX,minY,width,height,pixelBuffer)
Gracias por la ayuda
Esta es una explicación perfecta. Gracias – I82Much
Preferiría que me explicaras que atribuir significa elegir cuál de los posibles tipos quieres que asuma un valor, mientras que el lanzamiento fuerza un valor en otro tipo, que puede o no tomarse. –