[英]Java: Fastest way to draw text?
I'm trying to write a program that just creates an image out of text (eg write "hello" on a white square and store the image), which sounds simple but it must be done quickly. 我正在尝试编写一个仅用文本创建图像的程序(例如,在白色正方形上写“ hello”并存储图像),这听起来很简单,但是必须尽快完成。 I tried the Java2D library but drawing onto a BufferedImage takes ~2 seconds to just draw the image, not even save or display it.
我尝试了Java2D库,但是绘制到BufferedImage上只需要2秒钟即可绘制图像,甚至不保存或显示图像。 I also tried Java-based CAPTCHA generators but they take much too long (5 seconds).
我还尝试了基于Java的CAPTCHA生成器,但是它们花费的时间太长(5秒)。
This seems like simple enough task to just draw text, but I'm frustrated that I can't do this faster than 2 seconds. 这看起来很简单,只需要绘制文本即可,但是令我沮丧的是我不能快于2秒。
Is there a way I can do this faster on my machine by some command line options (eg allocating more memory or priority)? 有什么办法可以通过某些命令行选项(例如分配更多的内存或优先级)在我的计算机上更快地完成此操作? Is there a particular Java library I ought to use, or some weird quirk to Java2D I should be aware of to make things faster?
有没有我应该使用的特定Java库,或者我应该意识到对Java2D的一些怪异的怪癖才能使事情变得更快?
This is my entire program. 这是我的整个程序。 I run this in Eclipse:
我在Eclipse中运行此命令:
import java.awt.*;
import java.awt.image.BufferedImage;
public class SimpleGraphics {
public static void main(String[] args) {
long time = System.currentTimeMillis();
String message = "Hello world";
int width = 100;
int height = 100;
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D graphics = img.createGraphics();
graphics.setColor(Color.black);
graphics.setFont(new Font("TimesRoman", Font.BOLD, 12));
FontMetrics fontMetrics = graphics.getFontMetrics();
int stringWidth = fontMetrics.stringWidth(message);
int stringHeight = fontMetrics.getAscent();
graphics.drawString(message, (width - stringWidth) / 2, height / 2 + stringHeight / 4);
System.out.println(System.currentTimeMillis() - time); //consistently ~2 seconds
}
}
I run my code from the command line (using JDK8 on Windows 7) and I get around 300ms. 我从命令行运行代码(在Windows 7上使用JDK8),大约需要300毫秒。
I modified your code to the following: 我将您的代码修改为以下内容:
import java.awt.*;
import java.awt.image.BufferedImage;
public class SimpleGraphics {
public static void main(String[] args) {
long time = System.currentTimeMillis();
for (int i = 0; i < 100; i++)
createImage();
System.out.println(System.currentTimeMillis() - time); //consistently ~2 seconds
}
public static void createImage()
{
String message = "Hello world";
int width = 100;
int height = 100;
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D graphics = img.createGraphics();
graphics.setColor(Color.black);
graphics.setFont(new Font("TimesRoman", Font.BOLD, 12));
FontMetrics fontMetrics = graphics.getFontMetrics();
int stringWidth = fontMetrics.stringWidth(message);
int stringHeight = fontMetrics.getAscent();
graphics.drawString(message, (width - stringWidth) / 2, height / 2 + stringHeight / 4);
}
}
I still get around 300ms. 我仍然有300毫秒左右的时间。
So the problem is not with the painting code. 因此,问题不在于绘画代码。
I don't know why you get 2 seconds, but there is obviously some overhead to loading the class. 我不知道为什么会花2秒,但是加载类显然有一些开销。 So all I can suggest is to do your image creation in batches to minimize the time.
因此,我只能建议分批创建映像,以最大程度地减少时间。
Timing each line individually gives a big jump at fontMetrics - so there is your culprit. 对每一行单独计时会极大地提高fontMetrics的效率-因此有罪魁祸首。 I dont know if other measuring classes (lineMetrics) will give you shorter time
我不知道其他测量类别(lineMetrics)是否会缩短您的时间
import java.awt.*;
import java.awt.image.BufferedImage;
public class SimpleGraphics {
public static void main(String[] args) {
long time = System.currentTimeMillis();
String message = "Hello world";
int width = 100;
int height = 100;
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
System.out.println(System.currentTimeMillis() - time); //consistently ~2 seconds
Graphics2D graphics = img.createGraphics();
graphics.setColor(Color.black);
graphics.setFont(new Font("TimesRoman", Font.BOLD, 12));
System.out.println("1 "+(System.currentTimeMillis() - time)); //consistently ~2 seconds
FontMetrics fontMetrics = graphics.getFontMetrics();
System.out.println("2 "+(System.currentTimeMillis() - time)); //consistently ~2 seconds
int stringWidth = fontMetrics.stringWidth(message);
System.out.println("3 "+(System.currentTimeMillis() - time)); //consistently ~2 seconds
int stringHeight = fontMetrics.getAscent();
System.out.println(System.currentTimeMillis() - time); //consistently ~2 seconds
graphics.drawString(message, (width - stringWidth) / 2, height / 2 + stringHeight / 4);
System.out.println(System.currentTimeMillis() - time); //consistently ~2 seconds
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.