Java - BufferedImage 到 int[] 像素似乎已损坏

Java - BufferedImage to int[] pixels seems corrupted

我一直在尝试为每个像素使用 int 数组来显示图像 (BufferedImage),但每次我将数组作为参数传递时,结果都是损坏的 image.The图片没有 alphatransparent 像素。

Screenshot of result

What it should have displayed

SpriteSheet Class

public class SpriteSheet {
    public int width;
    public int height;
    public int[] pixels;
    BufferedImage image;


public SpriteSheet(String path) {
        image = null;
        try {
            image = ImageIO.read(SpriteSheet.class.getResourceAsStream(path));
        } catch (IOException ex) {
            Logger.getLogger(SpriteSheet.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (image == null) {
            return;
        }
        this.width = image.getWidth();
        this.height = image.getHeight();
        pixels = image.getRGB(0, 0, width, height, null, 0, width);
    }

}

显示Class

public class Display {
    private GameWindow displayWin;
    private BufferedImage displayImage;
    public int[] imagePixels;
    private BufferStrategy graphBuffer;
    private SpriteSheet sheet; 
    private int width;
    private int height;

    public Display(int width,int height,GameWindow win,SpriteSheet sheet) {
        this.displayImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        this.imagePixels = ((DataBufferInt) this.displayImage.getRaster().getDataBuffer()).getData();
        this.sheet=sheet;
        this.width=width;
        this.height=height;
        this.displayWin = win;
        this.displayWin.createBufferStrategy(3);
        this.graphBuffer= displayWin.getBufferStrategy();
    }

    public void renderFinal(){
        Level test = new Level(this.sheet, 1);
        test.render(this);
        Graphics g = graphBuffer.getDrawGraphics();
        g.drawRect(0, 0, width, height);
        g.drawImage(this.displayImage,0, 0,this.displayImage.getWidth(),this.displayImage.getHeight(), null);
        g.dispose();
        graphBuffer.show();
    }

    public int getWidth(){
        return this.width;
    }
    public int getHeight(){
        return this.height;
    }
}

等级Class

public class Level {

    private SpriteSheet levelSheet;
    private int level;

    public Level(SpriteSheet levelSheet,int newLevel) {
        this.levelSheet = levelSheet;
        this.level=newLevel;
    }

    public void render(Display displayLevel){
        if(this.level == 1){
            for (int y = 8; y <280; y++) {
                for (int x=0; x < 230; x++) {
                    displayLevel.imagePixels[x+y*displayLevel.getWidth()]
                            = this.levelSheet.pixels[x+y*displayLevel.getWidth()];
                }
            }
        }        
    }

}

例如,我想将图像从 0 剪切到 230,从 8 剪切到 280。这似乎是您正在尝试执行的操作。将一个图像部分剪切成另一个图像。图片大小不同,因此在传输时必须考虑宽度,如您所见,wcxhc 为 500x500

我使用以下

public void test() {
String image=".............";
BufferedImage bim=null;
try {
  bim=ImageIO.read(new File(image));
}
catch (Exception ex) { System.out.println("error in b "+ex); }
int wc=bim.getWidth(), hc=bim.getHeight();
int[] pix2=bim.getRGB(0, 0, wc, hc, null, 0, wc);
int[] pix=new int[500*500];
for (int y = 8; y <280; y++) {
            for (int x=0; x < 230; x++) {
                pix[x+y*500]
                        = pix2[x+y*wc];
            }
        }
  BufferedImage bm=new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
  bm.setRGB(0, 0, 500, 500, pix, 0, 500);

}

}

您必须小心图像编码:颜色或灰度级。

使用 BufferedImage,您有两个 "good" 解决方案来访问像素。 getRGB() 很简单,但要慢得多。

1 - 使用光栅更容易,因为它会自动处理编码,但速度较慢。

WritableRaster r = image.getRaster() ;
for (int y=0, nb=0 ; y < image.getHeight() ; y++)
    for (int x=0 ; x < image.getWidth() ; x++, nb++)
        pixels[nb] = r.getSample(x, y, 0) ; // For a gray level image.

2 - 使用 DataBuffer,速度最快,因为直接访问像素,但您必须处理编码。

switch ( image.getType() )
    {
    case BufferedImage.TYPE_BYTE_GRAY : // Classical gray level images.
        byte[] bb = ((DataBufferByte)image.getRaster().getDataBuffer()).getData() ;
        for (int i=0 ; i < bb.length ; i++)
            pixels[i] = bb[i] & 0xFF ;
        break ;
    }