Java 如何从大缓冲区中快速获取小图像

Java 如何从大缓冲区中快速获取小图像,java,performance,image,bufferedimage,clip,Java,Performance,Image,Bufferedimage,Clip,我有一个BuffereImage,一个大小(100mb)为6720x9239像素的图像,需要许多像素为60x60的小图像 首先,我使用了我在网上找到的代码 BufferedImage bi= ImageIO.read(new File(filename)); ...... //in paint() Image b=createImage(new FilteredImageSource(bi.getSource(), new CropImageFilter(x, y ,

我有一个BuffereImage,一个大小(100mb)为6720x9239像素的图像,需要许多像素为60x60的小图像

首先,我使用了我在网上找到的代码

 BufferedImage bi= ImageIO.read(new File(filename));
    ......
//in paint()
Image b=createImage(new FilteredImageSource(bi.getSource(),
        new CropImageFilter(x, y , 60, 60))); 
每个小图像需要等待1到5秒,速度非常慢,因为我的应用程序需要50个图像,这意味着ppl必须在50到5*50秒之间等待8秒,才能重新加载面板,所以我将其更改为

BufferedImage bi= ImageIO.read(new File(filename));
    ......
//in paint()
BufferedImage a = imageMap.getSubimage(x, y , 60, 60);
            Image b = createImage(a.getSource());

我真的很高兴现在我不得不让全世界都知道这一点

哦,我的上帝,你解决了我的问题,这让我困惑了大约5天。我刚把问题打好,就要提交了。显然(现在我知道使用图像是可行的)当你在g2d中使用BuffereImage.drawImage(图像,at,this)时,绘图要比使用图像慢得多。大约慢50倍。通过将BuffereImage转换为图像(我不知道您可以这样做,如果不这样做就可以解决问题),如下所示: 在loadBullets函数中:

        BufferedImage a;
    Image b;
 a = spriteSheetPositive.getSubimage(
                //going to use the same image 252 times until I get the motherload of data string converted to the format:
                //sprites[shotId]=spriteSheetPositive.getSubimage(x, y, width, height);
                520, //x  520,1,536,16 (small lime star) id=100
                1, //y
                16, //width
                15 //height
                );
        b= createImage(a.getSource());
        sprites[shotID]=b;
        for (int i = 0; i < Projectiles.size(); i++) {


        Shot02 m = (Shot02) Projectiles.get(i);
        //m.getImage();
      //  g2d.drawImage(m.getImage(), m.getIntX(), m.getIntY(), this);


        AffineTransform at = new AffineTransform();
        // 4. translate it to the center of the component
        at.translate(m.getDrawX(), m.getDrawY());
        // 3. do the actual rotation

        at.rotate(m.getAngle()); //rotation is Clockwise
        g2d.drawImage(m.getImage(), at, this);


    }
我现在可以使用精灵表中的图像作为投射精灵,在屏幕上同时显示多达1000个精灵,没有延迟!万岁

我原来的问题是: 这是“绘制”功能中的代码:

        BufferedImage a;
    Image b;
 a = spriteSheetPositive.getSubimage(
                //going to use the same image 252 times until I get the motherload of data string converted to the format:
                //sprites[shotId]=spriteSheetPositive.getSubimage(x, y, width, height);
                520, //x  520,1,536,16 (small lime star) id=100
                1, //y
                16, //width
                15 //height
                );
        b= createImage(a.getSource());
        sprites[shotID]=b;
        for (int i = 0; i < Projectiles.size(); i++) {


        Shot02 m = (Shot02) Projectiles.get(i);
        //m.getImage();
      //  g2d.drawImage(m.getImage(), m.getIntX(), m.getIntY(), this);


        AffineTransform at = new AffineTransform();
        // 4. translate it to the center of the component
        at.translate(m.getDrawX(), m.getDrawY());
        // 3. do the actual rotation

        at.rotate(m.getAngle()); //rotation is Clockwise
        g2d.drawImage(m.getImage(), at, this);


    }

这是Shot02类中的代码,用于控制项目符号使用的图像。同样,如果我取消对第二个选项的注释并使用BuffereImage,程序会像疯了一样慢下来。

哦,天哪,你解决了困扰我5天的问题。我刚把问题打好,就要提交了。显然(现在我知道使用图像是可行的)当你在g2d中使用BuffereImage.drawImage(图像,at,this)时,绘图要比使用图像慢得多。大约慢50倍。通过将BuffereImage转换为图像(我不知道您可以这样做,如果不这样做就可以解决问题),如下所示: 在loadBullets函数中:

        BufferedImage a;
    Image b;
 a = spriteSheetPositive.getSubimage(
                //going to use the same image 252 times until I get the motherload of data string converted to the format:
                //sprites[shotId]=spriteSheetPositive.getSubimage(x, y, width, height);
                520, //x  520,1,536,16 (small lime star) id=100
                1, //y
                16, //width
                15 //height
                );
        b= createImage(a.getSource());
        sprites[shotID]=b;
        for (int i = 0; i < Projectiles.size(); i++) {


        Shot02 m = (Shot02) Projectiles.get(i);
        //m.getImage();
      //  g2d.drawImage(m.getImage(), m.getIntX(), m.getIntY(), this);


        AffineTransform at = new AffineTransform();
        // 4. translate it to the center of the component
        at.translate(m.getDrawX(), m.getDrawY());
        // 3. do the actual rotation

        at.rotate(m.getAngle()); //rotation is Clockwise
        g2d.drawImage(m.getImage(), at, this);


    }
我现在可以使用精灵表中的图像作为投射精灵,在屏幕上同时显示多达1000个精灵,没有延迟!万岁

我原来的问题是: 这是“绘制”功能中的代码:

        BufferedImage a;
    Image b;
 a = spriteSheetPositive.getSubimage(
                //going to use the same image 252 times until I get the motherload of data string converted to the format:
                //sprites[shotId]=spriteSheetPositive.getSubimage(x, y, width, height);
                520, //x  520,1,536,16 (small lime star) id=100
                1, //y
                16, //width
                15 //height
                );
        b= createImage(a.getSource());
        sprites[shotID]=b;
        for (int i = 0; i < Projectiles.size(); i++) {


        Shot02 m = (Shot02) Projectiles.get(i);
        //m.getImage();
      //  g2d.drawImage(m.getImage(), m.getIntX(), m.getIntY(), this);


        AffineTransform at = new AffineTransform();
        // 4. translate it to the center of the component
        at.translate(m.getDrawX(), m.getDrawY());
        // 3. do the actual rotation

        at.rotate(m.getAngle()); //rotation is Clockwise
        g2d.drawImage(m.getImage(), at, this);


    }

这是Shot02类中的代码,用于控制项目符号使用的图像。同样,如果我取消对第二个选项的注释并使用BuffereImage,程序会像疯了一样慢下来。

原因很明显。第二幅图像与原始图像共享数据,而第一幅图像不共享数据。因此,这两者并不等同,这取决于你想用它做什么(在你的情况下,第二个显然是更好的选择,不仅仅是出于性能方面的原因),原因很明显。第二幅图像与原始图像共享数据,而第一幅图像不共享数据。因此,这两者并不等同,这取决于您想用它做什么(在您的情况下,第二个显然是更好的选择,不仅仅是出于性能原因)