代码之家  ›  专栏  ›  技术社区  ›  Mike B

Java Applet——图像输出性能问题

  •  2
  • Mike B  · 技术社区  · 16 年前

    我有一个Java小应用程序,我正在编辑和运行性能问题。更具体地说,小程序生成一个图像,我需要将其导出到客户机。

    这真的是在概念验证阶段,所以请放心。现在,图像将在预先定义的位置导出到客户机(这将在将来被保存对话框或其他内容替换)。但是,对于32kb文件,该过程需要将近15秒的时间。

    我做了一些“按臀部拍摄”的分析,在这个分析过程中,我以逻辑间隔向控制台打印消息。令我惊讶的是,我发现瓶颈似乎与实际的数据流写入过程有关,而不是与jpeg编码有关。

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

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

    下面是魔法发生的代码块:

    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;
    }
    
    3 回复  |  直到 16 年前
        1
  •  1
  •   Serxipc    16 年前

    如果不需要图像数据字节数组,可以直接对文件进行编码:

    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);
    //...
    
        2
  •  2
  •   Michael Myers KitsuneYMG    16 年前

    你可能想看看 ImageIO .

    我认为造成性能问题的原因是 byteToString . 你 从未 希望在循环中进行串联。你可以用 String(byte[]) 相反,您不需要将字节转换成字符串。

        3
  •  1
  •   Pierre Buyle    16 年前

    您也可以使用标准 ImageIO API(Cu.Sun.Idv.CoDe.jPEG包中的类不是核心Java API的一部分)。

    String myFile="C:" + File.separator + "tmpfile.jpg";
    File f = new File(myFile);
    ImageIO.write(biFullView, "jpeg", f);