2

I want to store RGB values in a pixel array like so:

pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

where image is:

BufferedImage image = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB);

I read the file using ImageIO and it read fine, it's this part that's the problem. Here's the error:

Exception in thread "main" java.lang.ClassCastException: java.awt.image.DataBufferByte cannot be cast to java.awt.image.DataBufferInt
at SpritePractice.render(SpritePractice.java:114)
at SpritePractice.run(SpritePractice.java:75)
at SpritePractice.start(SpritePractice.java:124)
at SpritePractice.main(SpritePractice.java:132)

And pixels is an int array like so: int[] pixels
What do I do? As a side question, can somebody explain casting and what it does? thanks!

EDIT:

Printed out image.getRaster().getDataBuffer() on console

Heres output:

java.awt.image.DataBufferByte@716925b0

Clearly there's something wrong here. I specified that BufferedImage image = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB); and it's reading DataBufferByte...

user2052855
  • 23
  • 1
  • 2
  • 5
  • here you go http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html – Nishant Nov 16 '13 at 19:19
  • I don't see why this doesn't work, BufferedImage.TYPE_INT_RGB should store the image data in an int[], it works for me. ((DataBufferInt) img.getRaster().getDataBuffer()) .getData() confirms it – arynaq Nov 16 '13 at 19:30
  • Are you sure that is the image causing the error and not some other image? – arynaq Nov 16 '13 at 19:31
  • It's the same image. Not getting any errors reading it. – user2052855 Nov 16 '13 at 19:49
  • "image = new BufferedImage(...) " and "I read the file using ImageIO and it read fine"... How do you do this? And are you sure `image` is the same after reading? There's obviously more to your code than what you have posted here. Please post the relevant code (or preferably an SSCCE). – Harald K Nov 18 '13 at 08:53

3 Answers3

2

You are probably doing it wrong. :-)

BufferedImage image = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB);

...should create an image with an IntegerInterleavedRaster and DataBufferInt (it does for me on OS X, using all my installed Java 6 and 7 JREs). Try printing the raster and the data buffer right after creation. I'm sure it will print what you originally expected.

Speculative answer below:

You haven't posted the relevant parts of your code, but I would guess based on the comments that you are a) creating an empty image and assigning it to image, then b) reading another image using ImageIO and assigning the result to image, replacing the previous value of image. The image now has a raster and data buffer of type byte. You then try to cast to int type, and boom.

Now, it is possible to make ImageIO read into a pre-created BufferedImage, or just specify the type. But this is plugin- and source-specific (ie: there's no guarantee it will support TYPE_INT_RGB). To query the reader what image layouts it supports, do something like:

ImageInputStream stream = ...;
Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);
if (readers.hasNext()) {
    ImageReader reader = readers.next();

    try {
        reader.setInput(stream);

        ImageReadParam param = reader.getDefaultReadParam();

        Iterator<ImageTypeSpecifier> specs = reader.getImageTypes();

        while (specs.hasNext()) {
            ImageTypeSpecifier spec = specs.next();

            if (/*spec is for TYPE_INT_RGB*/) {
                // Either pass your pre-allocated image:
                reader.setDestination(image); 

                // *OR* simply tell the reader what type you like the result to be:
                reader.setDestinationType(spec);
            }
        }

        // TODO: Handle the case where there's no match among the ImageTypeSpecifiers

        // In case image was passed, it will be the same image returned here
        image = reader.read(0, param); 
    }
    finally {
        reader.dispose();
    }
}

Casting does what it has always done, but I don't think that is your problem here. ;-)

Harald K
  • 26,314
  • 7
  • 65
  • 111
0

image.getRaster().getDataBuffer()).getData(); is of type java.awt.image.DataBufferByte as inferred from the exception.

You are attempting to cast i.e convert java.awt.image.DataBufferByte to java.awt.image.DataBufferInt which do not lie in the same inheritance hierarchy.

Remember this,

You can cast a sub type to super type (Liskov Substitution Principle).
When casting a super type to sub type a `ClassCasteException` will be thrown.
Also, if you attempt to cast classes which do not lie in the same inheritance  
hierarchy will always throw `ClassCasteException` at runtime.
Nishant
  • 1,142
  • 1
  • 9
  • 27
  • Shouldn't it be a DataBufferInt since I set the BufferedImage to type: `TYPE_INT_RGB`? – user2052855 Nov 16 '13 at 19:52
  • @user2052855 [this](http://stackoverflow.com/questions/15839223/java-awt-image-databufferbyte-cannot-be-cast-to-java-awt-image-databufferint) can help you – Nishant Nov 16 '13 at 20:13
-1

This is not so hard to understand:

DataBufferByte and DataBufferInt both extend DataBuffer so they are basically on different branches of the class hierarchy.

This is like trying to cast different implementations of the same interface to each other.

Adam Arold
  • 29,285
  • 22
  • 112
  • 207