Все,
Я делаю некоторую обработку изображения в Scala путем использования BufferedImages и Растровых объектов. Я пытаюсь получить все пиксели в буферизованном изображении со следующим кодом.
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)
Теперь, когда я читал в относительно больших файлах, это хорошо работает. Когда я читал в 20x20 файлы PNG, я получаю ArrayIndexOutOfBoundsException:
java.lang.ArrayIndexOutOfBoundsException: 1200
at sun.awt.image.ByteInterleavedRaster.getPixels(ByteInterleavedRaster.java:1050)
Я считал онлайн, что путь вокруг этой проблемы НЕ состоит в том, чтобы предварительно выделить pixelBuffer, но вместо этого передать в нулевом значении и использовать то, возвращенное методом Raster.getPixels.
Вот моя проблема. Когда я делаю наивный подход и просто передаю Ноль как последний аргумент:
val pixels = raster.getPixels(0,0,width,height,Nil)
Я получаю ошибку
error: overloaded method value getPixels with alternatives (Int,Int,Int,Int,Array[Double])Array[Double] (Int,Int,Int,Int,Array[Float])Array[Float] (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
Какая-либо идея, как сказать компилятору явно, что я хочу метод с Международным массивом как последний параметр, а не массив Плавающий?
Править: Как ответ указывает, я путал Ноль с пустым указателем. Ноль является пустым списком. Посмотрите следующее сообщение в блоге
Кроме того, я должен указать, что массив за пределы исключением был мой отказ (как эти вещи часто). Проблема была, я предполагал, что растр имел 3 канала, но мое изображение имело 4 канала, так как я создал его тот путь. Я вместо этого предварительно выделяю массив следующим образом:
val numChannels = raster.getNumBands()
val pixelBuffer = new Array[Int](width*height*numChannels)
val pixels = raster.getPixels(minX,minY,width,height,pixelBuffer)
Спасибо за справку
(Предполагая, что вам нужен вопрос о том, как разрешить перегрузки, когда вам нужно передать null):
Так же, как и в Java, приписав тип, соответствующий перегрузке, которую вы хотите вызвать (в Java вы ' d, но это то же самое: утверждение статического типа для присвоения null
):
scala> object O { def m(i: Int, s: String): String = s * i; def m(i: Int, l: List[String]): String = l.mkString(":") * i }
defined module O
scala> O.m(23, null)
<console>:7: error: ambiguous reference to overloaded definition,
both method m in object O of type (i: Int,l: List[String])String
and method m in object O of type (i: Int,s: String)String
match argument types (Int,Null)
O.m(23, null)
^
scala> O.m(23, null: String)
res4: String = nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
scala> O.m(23, null: List[String])
java.lang.NullPointerException
at O$.m(<console>:5)
at .<init>(<console>:7)
at .<clinit>(<console>)
at RequestResult$.<init>(<console>:9)
at RequestResult$.<clinit>(<console>)
at RequestResult$scala_repl_result(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:981)
at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:981)
at scala.util.control.Exception$Catch.apply(Exception.scala:7...
scala>