All
Я делаю некоторые манипуляции с изображениями в Scala, используя объекты BufferedImages и Raster. Я пытаюсь получить все пиксели буферизованного изображения с помощью следующего кода.
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)
Теперь, когда я читаю в относительно больших файлах, это работает нормально. Когда я читаю файлы PNG размером 20x20, я получаю исключение ArrayIndexOutOfBoundsException:
java.lang.ArrayIndexOutOfBoundsException: 1200
at sun.awt.image.ByteInterleavedRaster.getPixels(ByteInterleavedRaster.java:1050)
Я прочитал онлайн , что решение этой проблемы состоит в том, чтобы НЕ предварительно выделять pixelBuffer, а вместо этого передавать нулевое значение и использовать значение, возвращенное методом Raster.getPixels.
Вот моя проблема. Когда я делаю наивный подход и просто передаю Nil в качестве последнего аргумента:
val pixels = raster.getPixels(0,0,width,height,Nil)
Я получаю ошибку
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)
Так что, очевидно, компилятор не может определить, какой из двух методов я пытаюсь вызвать; это неоднозначно. Если бы я использовал Java, я бы бросил ноль, чтобы сделать свое намерение явным. Я не могу понять, как получить такой же эффект в Scala. Вещи, которые я пробовал:
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
Любая идея, как явно указать компилятору, что я хочу метод с массивом Int в качестве последнего параметра, а не с массивом Float?
EDIT:
В ответе указывается, что Нил перепутал с нулем. Ноль пустой список. Смотрите следующее сообщение в блоге
Кроме того, я должен указать, что исключение массива за пределами границ было моей ошибкой (как это часто бывает). Проблема заключалась в том, что я предполагал, что растр имеет 3 канала, но у моего изображения было 4 канала, так как я создал его таким образом. Вместо этого я предварительно распределяю массив следующим образом:
val numChannels = raster.getNumBands()
val pixelBuffer = new Array[Int](width*height*numChannels)
val pixels = raster.getPixels(minX,minY,width,height,pixelBuffer)
Спасибо за помощь