我怎样才能提高拼图课程的速度?

时间:2011-03-12 19:46:44

标签: java image tiles bufferedimage

我正在开发一个涉及检索大量图像以用作图标的Java项目。以前,我有一个包含大量单个.png文件的文件夹 - 这个工作得相当好,但占用了大量空间并且相当难以处理。相反,我尝试编写一个类,允许我从一个更大的文件中提取ImageIcon格式的缩放图块。

花了一段时间,但我设法使用PixelGrabber和BufferedImage.setRGB()方法,使用我在Stack Overflow上找到的引用。你可以看到下面的课程(它可能会在某些地方使用一些改进):

/**
* Java tile grabbing class: Create ImageIcons from coordinates out of an image
*
* @author Protractor Ninja
* @version 1.00 2011/2/21
*/

import javax.swing.ImageIcon;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import java.awt.image.ImageObserver;
import java.awt.Image;
import java.io.File;
import java.lang.Exception;
import javax.swing.*;
import java.awt.image.WritableRaster;
import java.util.*;

public class TileGrabber {

 private BufferedImage image;
 private File imageFile;
 private PixelGrabber grabber;
 private int tileWidth;
 private int tileHeight;
 private int[] pixels;

 /*
  * Creates a tile grabber object using a filepath and tile heights.
  * Tiles should start at zero pixels.
  */
 public TileGrabber(String path, int tWidth, int tHeight) {
    try {
        image = ImageIO.read(this.getClass().getResourceAsStream("/" + path.replaceAll("^/", "")));
        pixels = new int[tWidth*tHeight];
        tileWidth = tWidth;
        tileHeight = tHeight;
    } catch (Exception e) {
        e.printStackTrace();
    }
 }

 /*
  * Same as before, but uses an already-created BufferedImage file.
  */
 public TileGrabber(BufferedImage img, int tWidth, int tHeight) {
    try {
        image = img;
        pixels = new int[tWidth*tHeight];
        tileWidth = tWidth;
        tileHeight = tHeight;
    } catch (Exception e) {
        e.printStackTrace();
    }
 }

 public void setImagePath(String path) {
    try {
        image = ImageIO.read(this.getClass().getResourceAsStream("/" + path.replaceAll("^/", "")));
    } catch (Exception e) {
        e.printStackTrace();
    }
 }

 /*
  * Creates an ImageIcon object from tile coordinates on an image.
  */
 public ImageIcon grabTile(int x, int y, int scale) {
    x = x*tileWidth;
    y = y*tileHeight;
    grabber = new PixelGrabber(image, x, y, tileWidth, tileHeight, pixels, 0, tileWidth);
    try {
        grabber.grabPixels();
    } catch (Exception e) {
        e.printStackTrace();
    }
    Image i = getImageFromArray(pixels, tileWidth, tileHeight).getScaledInstance(tileWidth*scale, tileHeight*scale, Image.SCALE_FAST);
    return new ImageIcon(i);
 }

 /*
  * Creates an Image from an array of pixels and specified heights.
  * Retrieved and modified from a stackoverflow.com question
  */
 public Image getImageFromArray(int[] pixels, int width, int height) {
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    image.setRGB(0,0,width,height,pixels,0, width);
    return image;
 }

 /**
  * For testing purposes.
  */
 public static void main(String[] args) {
    JFrame window = new JFrame("Hello, this is a test");
    window.setBounds(0,0,550,500);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    TileGrabber grabber = new TileGrabber("terrain.png", 16, 16);
    JLabel label = new JLabel(grabber.grabTile(12,8,5));
    window.getContentPane().add(label);
    window.setVisible(true);
 }


}

唯一的问题是,启动过程中的主要延迟是加载所有图标时发生的延迟,而我真的不确定如何让它更快 - 我真的很想让它变得如此用户不必等待很长时间才能启动程序。

我有什么方法可以改进我的代码,或者,是否有另一种更快的方法来做我正在尝试做的事情?

非常感谢你的时间。

2 个答案:

答案 0 :(得分:1)

您是否通过分析器运行代码以尝试查明缓慢的来源?我知道这不是一个直接有用的答案,但是如果没有分析就试图跟踪性能问题会浪费很多时间。

可能有帮助的替代机制是延迟获取图像直到需要它们,显然如果您需要程序启动时的所有图像,这将无济于事。

答案 1 :(得分:0)

由于您已经有BufferedImage,因此您可能会看到getSubimage()是否更快。

附录:这是一个example,可以让您使用现有的复合材料进行测试。