0

Recently I have been attempting to scale pixel arrays (int[]) in Java. I used .setRGB() to add all my pixel data into the BufferedImage. BufferedImage then offers a function called .getScaledInstance(). This should work great for my purposes, but I ran into a problem. .getScaledInstance() returns a Image, not a BufferedImage. With an Image object, I cannot use .getRGB() to add all the pixel data (in int[] form) from the scaled Image back into an array. Is there a way to get raw pixel data from an Image file? Am I missing something? I looked at other questions and did a bit of googling, and they only seemed to be wanting to get picture data in a different form of array (int[][]) or in bytes. Any help would be appreciated, thanks. Also, Sprite is a class I made that is being used. Here is my code:

public Sprite scaleSprite(Sprite s, int newWidth, int newHeight){

    BufferedImage image = new BufferedImage(s.getWidth(), s.getHeight(),  BufferedImage.TYPE_INT_RGB);
    for(int y = 0; y < s.getHeight(); y++){
        for(int x = 0; x < s.getWidth(); x++){
            image.setRGB(x, y, s.getPixel(x, y));

        }
    }
    Image newImage = image.getScaledInstance(newWidth, newHeight, Image.SCALE_AREA_AVERAGING);
    Sprite newS = new Sprite(newWidth, newHeight);
    int[] pixels = new int[newWidth * newHeight];
    newImage.getRGB(0, 0, newWidth, newHeight, pixels, 0, newWidth); //This is where I am running into problems. newImage is an Image and I cannot retrieve the raw pixel data from it.

    newS.setPixels(pixels);
    return newS;
}
Sock314
  • 157
  • 9
  • possible duplicate of [How can I resize an image using Java?](http://stackoverflow.com/questions/244164/how-can-i-resize-an-image-using-java) – Harald K Mar 15 '15 at 21:04

2 Answers2

1

To be clear, getScaledInstance() is a method of Image, not BufferedImage. You don't generally want to revert to working directly with the Image superclass once you're working with BufferedImage; Image is really not easy to work with.

Please see if this will help: How to scale a BufferedImage

Or from Scaling a BufferedImage, where they yield the following example:

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;

public class Main {
  public static void main(String[] argv) throws Exception {
    BufferedImage bufferedImage = new BufferedImage(200, 200,
        BufferedImage.TYPE_BYTE_INDEXED);

    AffineTransform tx = new AffineTransform();
    tx.scale(1, 2);

    AffineTransformOp op = new AffineTransformOp(tx,
        AffineTransformOp.TYPE_BILINEAR);
    bufferedImage = op.filter(bufferedImage, null);
  }

This will give you the ability to scale entirely at the level of BufferedImage. From there you can apply whatever sprite specific or array data algorithm you wish.

Community
  • 1
  • 1
1

You can draw the resulting Image onto a BufferedImage like this:

Image newImage = image.getScaledInstance(newWidth, newHeight, Image.SCALE_AREA_AVERAGING);
BufferedImage buffImg = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2 = (Graphics2D) buffImg.getGraphics();
g2.drawImage(newImage, 0, 0, 10, 10, null);
g2.dispose();

Or you can scale the image directly by drawing it on another BufferedImage:

BufferedImage scaled = new BufferedImage(newWidth, newWidth, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2 = (Graphics2D) scaled.getGraphics();
g2.drawImage(originalImage, 0, 0, newWidth, newWidth, 0, 0, originalImage.getWidth(), originalImage.getHeight(), null);
g2.dispose();

The second approach will work correctly if the two BufferedImages have the same aspect ratio.

Titus
  • 22,031
  • 1
  • 23
  • 33
  • Yes, but then the OP is moving from BufferedImage to Image to BufferedImage again, which seems like a lot of unnecessary hoops to jump through. Besides, BufferedImage was designed precisely to allow direct access to image data; an apparent requirement of the OP. –  Mar 15 '15 at 22:11
  • @tgm1024 I know, that is why I've included the second approach which doesn't use an `Image`. It scales the original `BufferedImage` by drawing it to a new `BufferedImage` which has the required size. – Titus Mar 15 '15 at 22:16
  • @Indeed. My apologies. Infact `Graphics2D.drawImage()` is even overloaded to allow the [AffineTransform](http://docs.oracle.com/javase/8/docs/api/java/awt/Graphics2D.html#drawImage-java.awt.Image-java.awt.geom.AffineTransform-java.awt.image.ImageObserver-) should the OP desire full control over which scale is occurring. –  Mar 15 '15 at 22:23
  • maybe consider making the 2nd example the first example, with a strong caveat that the first example is not an ideal approach for the OP? –  Mar 16 '15 at 13:08