【问题标题】:Retrieving pixel data from Java Image从 Java 图像中检索像素数据
【发布时间】:2015-05-17 21:55:12
【问题描述】:

最近我一直在尝试在 Java 中缩放像素数组 (int[])。我使用 .setRGB() 将所有像素数据添加到 BufferedImage 中。然后 BufferedImage 提供了一个名为 .getScaledInstance() 的函数。这应该很适合我的目的,但我遇到了一个问题。 .getScaledInstance() 返回一个图像,而不是一个 BufferedImage。对于 Image 对象,我不能使用 .getRGB() 将缩放后的 Image 中的所有像素数据(以 int[] 形式)添加回数组中。有没有办法从图像文件中获取原始像素数据?我错过了什么吗?我查看了其他问题并进行了一些谷歌搜索,他们似乎只想以不同形式的数组(int [] [])或字节获取图片数据。任何帮助将不胜感激,谢谢。此外,Sprite 是我制作的一个正在使用的类。这是我的代码:

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;
}

【问题讨论】:

标签: java image bufferedimage scaling


【解决方案1】:

您可以将生成的Image 绘制到BufferedImage 上,如下所示:

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();

或者您可以通过在另一个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();

如果两个BufferedImages 具有相同的纵横比,则第二种方法将正常工作。

【讨论】:

  • 是的,但是随后 OP 再次从 BufferedImage 移动到 Image 到 BufferedImage,这似乎需要跳过很多不必要的障碍。此外,BufferedImage 被精确设计为允许直接访问图像数据; OP 的明显要求。
  • @tgm1024 我知道,这就是为什么我包含了不使用Image 的第二种方法。它通过将原始BufferedImage 绘制为具有所需大小的新BufferedImage 来缩放原始BufferedImage
  • @确实。我很抱歉。事实上Graphics2D.drawImage() 甚至被重载以允许AffineTransform 如果 OP 希望完全控制正在发生的规模。
  • 也许考虑将第二个示例作为第一个示例,并强烈警告第一个示例不是 OP 的理想方法?
【解决方案2】:

需要明确的是,getScaledInstance()Image 的方法,而不是BufferedImage。使用BufferedImage 后,您通常不想恢复为直接使用Image 超类; Image 真的不好相处。

请看看这是否有帮助:How to scale a BufferedImage

或者来自Scaling a BufferedImage,它们产生以下示例:

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);
  }

这将使您能够完全在BufferedImage 级别进行扩展。从那里你可以应用任何你想要的精灵特定或数组数据算法。

【讨论】:

    猜你喜欢
    • 2012-02-28
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多