如何真正快速地从大 Bufferedimage 中获取小图像

Posted

技术标签:

【中文标题】如何真正快速地从大 Bufferedimage 中获取小图像【英文标题】:How to get small images from big Bufferedimage really fast 【发布时间】:2011-06-11 18:21:05 【问题描述】:

我有一个 BufferedImage 大小 (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 秒之间等待 w8 才能重新加载面板,所以我将其改为

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

现在不得不让世界知道这一点,感觉真的很开心

【问题讨论】:

那么原因很明显。第二张图像与原始图像共享数据,而第一张图像则不共享。所以这两者是不等价的,这取决于你想用它做什么(在你的情况下,第二个显然是更好的选择,不仅仅是出于性能原因) 【参考方案1】:

天哪,您解决了困扰我 5 天的问题。我刚刚完成了问题的输入并准备提交。显然(现在我知道使用图像有效)当您在 g2d.drawImage(Image, at, this) 中使用缓冲图像时,绘图比使用图像慢得多。像慢 50 倍的东西。通过将 BufferedImages 转换为图像(我不知道你可以这样做,这样可以解决问题),如下所示: 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;

我现在可以将精灵表中的图像用作弹丸精灵,一次在屏幕上显示多达 1,000 个,没有延迟!万岁!

我原来的问题:

这是paint函数中的代码:

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


    

我正在开发一款平台视角射击游戏。我从使用简单的 imageicon 图像切换到从 sprite 表创建为 subImage 的 bufferedImage。然而,由于该程序在屏幕上只有 20 个弹丸,而之前我可以有多达 1000 个左右。

private void loadBullets() //is done only once, when the window starts
    // Get Image
    ImageIcon icon = new ImageIcon(this.getClass().getResource("AbsoluteWin\\CustomShotsPositive.png"));
    Image image = icon.getImage();

    // Create empty BufferedImage, sized to Image
    BufferedImage spriteSheetPositive =
            new BufferedImage(
            image.getWidth(null),
            image.getHeight(null),
            Transparency.BITMASK);


    // Draw Image into BufferedImage
    Graphics g = spriteSheetPositive.createGraphics();
    g.drawImage(image, 0, 0, null);

    int shotID = 1;
    System.out.println(shotID);

    while (shotID <= length) //fills the array with the bullets from the sprite sheet spriteSheetPositive
        sprites[shotID] = spriteSheetPositive.getSubimage(
                //going to use the same image 252 times until I get the coordinates for all the other sub-images
                //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
                );

        shotID += 1;

    
    System.out.println(shotID);

Shot02 类:

        ImageIcon ii =
            new ImageIcon(this.getClass().getResource("missile.png"));
    image = ii.getImage();

   //image=Destination.sprites[100];//is the source

这是 Shot02 类中的代码,用于控制子弹使用的图像。同样,如果我取消注释第二个选项并使用 BufferedImages,程序会像疯了一样变慢。

【讨论】:

以上是关于如何真正快速地从大 Bufferedimage 中获取小图像的主要内容,如果未能解决你的问题,请参考以下文章

如何优化限制查询以更快地从大表中访问数据?

如何有效地从大 txt 文件中读取字符串

直播预告 | 嵌入式BI如何将数据分析真正融入业务流程

Java订阅从大文件中读取新行

如何在 JPanel 中查看 BufferedImage?

如何从 java 中的组件获取 BufferedImage?