On Jul 5, 10:31 pm, Mark Triggs <mark.h.tri...@gmail.com> wrote:
> (defn bi-get-pixels
>   [#^BufferedImage bi]
>   (let [raster (.getData bi)
>         pixels (.getPixels raster 0 0 (.getWidth bi) (.getHeight bi)
>                            (cast (Class/forName "[I") nil))]
>     (vec pixels)))

This still generates a single reflection warning, but #^ints before
the cast fixes it. That gave me an idea:

(defn bi-get-pixels
  [#^BufferedImage bi]
  (vec (.. bi (getData)
           (getPixels 0 0 (.getWidth bi) (.getHeight bi)
                      #^ints (identity nil)))))

Which does the right thing with no warnings.

Thanks for the help,

-Phil

>
> Cheers,
>
> Mark
>
> On Jul 5, 10:18 pm, "philip.hazel...@gmail.com"
>
> <philip.hazel...@gmail.com> wrote:
> > Hi,
>
> > The following code works as expected:
>
> > (import 'javax.imageio.ImageIO 'java.io.File
> > 'java.awt.image.BufferedImage)
> > (defn bi-get-pixels
> >   [bi]
> >   (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> > nil))))
> > (bi-get-pixels (. ImageIO read (File. "/home/phil/prog/small-
> > test.png")))
>
> > But if *warn-on-reflection* is true, it generates four warnings. If we
> > try to shut it up with a type hint:
>
> > (defn bi-get-pixels
> >   [#^BufferedImage bi]
> >   (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> > nil))))
>
> > Exception in thread "main" java.lang.IllegalArgumentException: More
> > than one matching method found: getPixels (imagio-test.clj:7)
> >         at clojure.lang.Compiler.analyzeSeq(Compiler.java:4558)
> > ...
> > Caused by: java.lang.IllegalArgumentException: More than one matching
> > method found: getPixels
> >         at clojure.lang.Compiler.getMatchingParams(Compiler.java:2122)
> >         at clojure.lang.Compiler$InstanceMethodExpr.<init>
> > (Compiler.java:1159)
> >         at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:
> > 810)
> >         at clojure.lang.Compiler.analyzeSeq(Compiler.java:4551)
> >         ... 34 more
>
> > The problem here is that getPixels has three forms: 
> > (http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html)
> >  double[]       getPixels(int x, int y, int w, int h, double[] dArray)
> >           Returns a double array containing all samples for a
> > rectangle of pixels, one sample per array element.
> >  float[]        getPixels(int x, int y, int w, int h, float[] fArray)
> >           Returns a float array containing all samples for a rectangle
> > of pixels, one sample per array element.
> >  int[]  getPixels(int x, int y, int w, int h, int[] iArray)
> >           Returns an int array containing all samples for a rectangle
> > of pixels, one sample per array element.
>
> > In each case, if the final argument is NULL it is ignored, and if not
> > the array is populated with the return data from the call (generating
> > an error if it's not large enough).
>
> > Is it possible to specify which invocation of getPixels I intend
> > without passing an array? I've tried putting #^ints in some likely-
> > looking places, but nil can't be type-hinted and the others seem to
> > have no effect. I've also tried splitting the .. up:
>
> > (defn bi-get-pixels
> >   [#^BufferedImage bi]
> >   (let [rast (.getData bi)
> >         #^ints pi (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)]
> >     pi))
>
> > But this doesn't work either. I could do manual reflection on Raster
> > to get the correct method and .invoke it, but that seems far more
> > complicated than necessary. Any other ideas?
>
> > -Phil
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to