2

我有一个 Java Applet,我正在对其进行一些编辑并且遇到了性能问题。更具体地说,小程序生成一个我需要导出到客户端机器的图像。

这真的是在概念验证阶段,所以请耐心等待。目前,图像被导出到客户端机器的预定义位置(这将在未来被保存对话框或其他东西替换)。但是,对于一个 32kb 的文件,该过程需要将近 15 秒。

我已经完成了一些 'shoot-by-the-hip' 分析,在整个相关方法中以逻辑间隔将消息打印到控制台。令我惊讶的是,我发现瓶颈似乎与实际的数据流写入过程有关,而不是 jpeg 编码。

请记住,我只有 Java 及其方法的基本知识

所以慢慢来:p - 我主要是在寻找解决问题的建议,而不是解决方案本身。

这是发生魔法的代码块:

ByteArrayOutputStream jpegOutput = new ByteArrayOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(jpegOutput);
encoder.encode(biFullView);
byte[] imageData = jpegOutput.toByteArray();

String myFile="C:" + File.separator + "tmpfile.jpg";
File f = new File(myFile);

try {
dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(myFile),512));
dos.writeBytes(byteToString(imageData));
dos.flush();
dos.close();
}
catch (SecurityException ee) {
    System.out.println("writeFile: caught security exception");
}
catch (IOException ioe) {
    System.out.println("writeFile: caught i/o exception");
}

就像我提到的,使用 system.out.println() 我已经将性能瓶颈缩小到 DataOutputStream 块。使用具有不同硬件统计数据的各种机器似乎对整体性能影响不大。

任何指针/建议/方向将不胜感激。

编辑:根据要求,byteToString():

public String byteToString(byte[] data){
  String text = new String();
  for ( int i = 0; i < data.length; i++ ){
    text += (char) ( data[i] & 0x00FF );
  }
  return text;
}
4

3 回答 3

2

你可能想看看ImageIO

而且我认为性能问题的原因是循环输入byteToString. 您永远不想在循环中进行连接。您可以改用String(byte[])构造函数,但您实际上并不需要将字节转换为字符串。

于 2009-02-19T15:26:25.160 回答
1

如果您不需要图像数据字节数组,您可以直接编码到文件中:

String myFile="C:" + File.separator + "tmpfile.jpg";
File f = new File(myFile);
FileOutputStream fos = null;
try {
    fos = new FileOutputStream(f);
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(
                             new BufferedOutputStream(fos));
    encoder.encode(biFullView);
}
catch (SecurityException ee) {
    System.out.println("writeFile: caught security exception");
}
catch (IOException ioe) {
    System.out.println("writeFile: caught i/o exception");
}finally{
    if(fos != null) fos.close();
}

如果您需要字节数组来执行其他操作,最好将其直接写入 FileOutputStream:

//...
fos = new FileOutputStream(myFile));
fos.write(imageData, 0, imageData.length);
//...
于 2009-02-19T15:27:10.600 回答
1

您还可以使用标准ImageIO API(com.sun.image.codec.jpeg 包中的类不是核心 Java API 的一部分)。

String myFile="C:" + File.separator + "tmpfile.jpg";
File f = new File(myFile);
ImageIO.write(biFullView, "jpeg", f);
于 2009-03-09T11:22:35.577 回答