Я хочу смешать несколько изображений в java.awt.Graphics
, поэтому я пишу утилиты для этого. Я нахожу, что так медленно звонить 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;
}
}
Я хочу найти ресурс, который нужно инициализировать, чтобы я мог инициализировать его вручную.