为什么Java Graphics drawImage第一次运行缓慢

时间:2019-04-18 04:26:43

标签: java performance graphics

我想在java.awt.Graphics中混合一些图像,所以我编写了utils来做到这一点。我发现调用graphics.drawImage()太慢了;第一次需要2秒。我认为有些东西需要初始化,而且非常慢。

因此,我运行了一个基准测试以查找原因,并且得到了这样的结果,我发现第一次的step3调用很慢,我发现第一次的每个线程都会很慢。 我会继续前进。

StopWatch '0': running time (millis) = 1631
-----------------------------------------
ms     %     Task name
-----------------------------------------
00005  000%  create canvas
00095  006%  draw picture
00003  000%  step 1
00025  002%  step 2
01373  084%  step 3
00000  000%  step 4
00000  000%  step 5
00130  008%  save picture

StopWatch '2': running time (millis) = 1632
-----------------------------------------
ms     %     Task name
-----------------------------------------
00005  000%  create canvas
00093  006%  draw picture
00004  000%  step 1
00022  001%  step 2
01378  084%  step 3
00000  000%  step 4
00000  000%  step 5
00130  008%  save picture

StopWatch '1': running time (millis) = 1633
-----------------------------------------
ms     %     Task name
-----------------------------------------
00005  000%  create canvas
00095  006%  draw picture
00003  000%  step 1
00031  002%  step 2
01370  084%  step 3
00000  000%  step 4
00000  000%  step 5
00129  008%  save picture

StopWatch '1': running time (millis) = 115
-----------------------------------------
ms     %     Task name
-----------------------------------------
00001  001%  create canvas
00000  000%  draw picture
00000  000%  step 1
00005  004%  step 2
00000  000%  step 3
00000  000%  step 4
00000  000%  step 5
00109  095%  save picture

StopWatch '0': running time (millis) = 123
-----------------------------------------
ms     %     Task name
-----------------------------------------
00001  001%  create canvas
00000  000%  draw picture
00000  000%  step 1
00009  007%  step 2
00000  000%  step 3
00000  000%  step 4
00000  000%  step 5
00113  092%  save picture

StopWatch '2': running time (millis) = 127
-----------------------------------------
ms     %     Task name
-----------------------------------------
00001  001%  create canvas
00000  000%  draw picture
00000  000%  step 1
00014  011%  step 2
00000  000%  step 3
00000  000%  step 4
00000  000%  step 5
00112  088%  save picture

StopWatch '1': running time (millis) = 116
-----------------------------------------
ms     %     Task name
-----------------------------------------
00000  000%  create canvas
00001  001%  draw picture
00000  000%  step 1
00004  003%  step 2
00000  000%  step 3
00000  000%  step 4
00000  000%  step 5
00111  096%  save picture

StopWatch '0': running time (millis) = 113
-----------------------------------------
ms     %     Task name
-----------------------------------------
00001  001%  create canvas
00000  000%  draw picture
00001  001%  step 1
00004  004%  step 2
00000  000%  step 3
00000  000%  step 4
00000  000%  step 5
00107  095%  save picture

StopWatch '2': running time (millis) = 111
-----------------------------------------
ms     %     Task name
-----------------------------------------
00001  001%  create canvas
00000  000%  draw picture
00000  000%  step 1
00006  005%  step 2
00000  000%  step 3
00000  000%  step 4
00000  000%  step 5
00104  094%  save picture

我测试了很多次,结果是相同的。

我的基准代码:

import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import org.springframework.util.StopWatch;

public class ImageTest {

  static final Font roman = new Font("inherit", Font.PLAIN, 40);
  static final String basePath = "/Users/shiheng/Desktop/";

  public static void main(String[] args) throws Exception {
    final BufferedImage image = ImageIO.read(new File(basePath, "download.jpeg"));
    final BufferedImage overlay = ImageIO.read(new File(basePath, "images.jpeg"));
    List<Thread> threadList = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
      final int id = i;
      Runnable runnable = () -> {
        try {
          for (int j = 0; j < 3; j++) {
            benchmark(id, j, basePath, image, overlay);
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      };
      Thread thread = new Thread(runnable);
      thread.start();
      threadList.add(thread);
    }
    for (Thread thread : threadList) {
      thread.join();
    }
  }

  static void mark(StopWatch stopWatch, String note) {
    if (stopWatch.isRunning()) {
      stopWatch.stop();
    }
    stopWatch.start(note);
  }

  static void benchmark(int id, int i, String basePath, BufferedImage image, BufferedImage overlay)
      throws Exception {
    StopWatch stopWatch = new StopWatch(String.valueOf(id));

    mark(stopWatch, "create canvas");
    int w = Math.max(image.getWidth(), overlay.getWidth());
    int h = Math.max(image.getHeight(), overlay.getHeight());
    BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

    mark(stopWatch, "draw picture");
    int cw = overlay.getWidth() / 4 * 3;
    int ch = overlay.getHeight() / 4 * 3;
    ImageUtil imageUtil = ImageUtil.getInstance(combined);
    mark(stopWatch, "step 1");
    imageUtil.drawImage(image, i, i);
    mark(stopWatch, "step 2");
    imageUtil.drawImage(overlay.getScaledInstance(cw, ch, Image.SCALE_FAST), i, i);
    mark(stopWatch, "step 3");
    imageUtil.drawText("意大利炮!", 23 + i, 100 + i, roman, Color.PINK);
    mark(stopWatch, "step 4");
    imageUtil.drawText("意大利炮!", 29 + i, 100 + i, roman, Color.BLUE);
    mark(stopWatch, "step 5");
    imageUtil.drawText("意大利炮!", 26 + i, 100 + i, roman, Color.WHITE);

    mark(stopWatch, "save picture");
    ImageIO.write(combined, "PNG", new File(basePath, "combined.png"));
    stopWatch.stop();
    System.out.println(stopWatch.prettyPrint());
  }

}


我的实用程序代码:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;

public class ImageUtil {

  private final Graphics graphics;
  private final BufferedImage canvas;

  private ImageUtil(BufferedImage canvas) {
    this.canvas = canvas;
    this.graphics = canvas.getGraphics();
  }

  public static ImageUtil getInstance(BufferedImage canvas) {
    return new ImageUtil(canvas);
  }

  public ImageUtil drawText(String text, int x, int y, Font font, Color color) {
    graphics.setFont(font);
    graphics.setColor(color);
    graphics.drawString(text, x, y);
    return this;
  }

  public ImageUtil drawImage(Image image, int x, int y) {
    graphics.drawImage(image, x, y, null);
    return this;
  }

}

我想找到需要初始化的资源,以便可以手动对其进行初始化。

0 个答案:

没有答案