9

全部,

我正在通过使用 BufferedImages 和 Raster 对象在 Scala 中进行一些图像处理。我正在尝试使用以下代码获取缓冲图像中的所有像素。

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)

我在网上读到,解决这个问题的方法是不预先分配像素缓冲区,而是传入一个空值并使用 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,我会强制转换为 null 以明确我的意图。我不太清楚如何在 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 数组的方法吗?

编辑:正如答案指出的那样,我将 Nil 与 null 混为一谈。Nil 是一个空列表。请参阅以下博客文章

另外,我应该指出,数组越界异常是我的错(因为这些事情经常发生)。问题是我假设光栅有 3 个通道,但我的图像有 4 个通道,因为我是这样创建的。我改为按如下方式预分配数组:

val numChannels = raster.getNumBands() 

val pixelBuffer = new Array[Int](width*height*numChannels)
val pixels = raster.getPixels(minX,minY,width,height,pixelBuffer)

谢谢您的帮助

4

2 回答 2

17

(假设您需要在需要传递 null 时如何解决重载的问题):

就像您在 Java 中所做的那样,通过将类型对应于您希望调用的重载(在 Java 中您会强制转换,但它等同于:分配给 的静态类型的断言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>
于 2010-07-02T21:16:27.073 回答
5

Nilnull.

于 2010-07-02T21:06:07.503 回答