我想在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;
}
}
我想找到需要初始化的资源,以便可以手动对其进行初始化。