2010-11-04 78 views
5

根據Google Page Speed的建議,我想Specify image dimensions以「優化瀏覽器渲染」。Ant任務從PNG和JPEG文件中提取圖像尺寸(高度,寬度)?

指定爲所有 圖像的寬度和高度允許更快的渲染通過 消除對不必要 迴流和重新繪製的需要。

我研究如何通過圖像文件(PNG,JPEG)在我的靜態內容項目,並輸出遍歷每個圖像文件的路徑和文件名,以及以像素爲單位的高度和寬度的文件。然後我會使用它來幫助我通過使用src屬性數據來查找用於高度和寬度屬性的值來構建標記。

\images\logo.png,100,25 

我的第一個想法是尋找一個Ant任務,因爲我們的靜態內容的構建採用Ant用於其他用途(如在JavaScript和CSS文件使用YUI Compressor)。我也接受其他想法,包括解決這個問題的其他方法。我寧願不必手動完成這項工作。

回答

4

你可以試試這個https://github.com/mattwildig/image-size-report-task,我只是爲了這個問題而做的。

+0

至少ü試過+1 – 2010-11-08 15:23:58

+0

我這個執行,但沒有在答案之前更新此問題。我正在接受你的答案。謝謝。 – 2010-11-08 18:55:44

0

我不知道這樣的螞蟻任務可用,但它應該是相對簡單的寫一個。在PNG格式中,圖像大小存儲在IHDR標題文件的開頭。 Google上有許多PNG解析器樣本 - 例如this。把它包裝在螞蟻任務中,你就完成了。

1

這是我到目前爲止實施的(需要測試和清理)。基本上,使用Tutorial: Tasks using Properties, Filesets & Paths可以讓我開始使用Ant任務,並使用How to get image height and width using java?來提取圖像尺寸。我將在部署之前與馬特的答案進行比較。

從我的項目的測試構建腳本:

<project name="ImagesTask" basedir="." default="test"> 
    <target name="init"> 
     <taskdef name="images" classname="ImageInfoTask" classpath="..\dist\ImageTask.jar"/> 
    </target> 
    <target name="test" depends="init"> 
     <images outputFile="data/images.xml"> 
      <fileset dir="data" includes="images/**/*.jpg"/> 
      <fileset dir="data" includes="images/**/*.gif"/> 
      <fileset dir="data" includes="images/**/*.png"/> 
     </images> 
    </target> 
</project> 

的Java源(不含進口):

public class ImageInfoTask extends Task { 

    private String outputFile; 
    private List fileSetList = new ArrayList(); 
    private PrintStream outputFileStream; 

    public void setOutputFile(String outputFile) { 
     this.outputFile = outputFile.replace("/", File.separator); 
    } 

    public void addFileset(FileSet fileset) { 
     fileSetList.add(fileset); 
    } 

    protected void validate() { 
     if (outputFile == null) { 
      throw new BuildException("file not set"); 
     } 

     if (fileSetList.size() < 1) { 
      throw new BuildException("fileset not set"); 
     } 
    } 

    protected void openOutputFile() throws IOException { 
     FileOutputStream out = new FileOutputStream(this.outputFile); 

     // Connect print stream to the output stream 
     this.outputFileStream = new PrintStream(out, true, "UTF-8"); 

     this.outputFileStream.println("<images>"); 
    } 

    protected void writeImgToOutputFile(String filename, Dimension dim) { 
     String imgTag = " <img src=\"/" + filename.replace("\\", "/") 
       + "\" height=\"" + dim.height + "\" width=\"" + dim.width 
       + "\" />"; 

     this.outputFileStream.println(imgTag); 
    } 

    protected void closeOutputFile() { 
     this.outputFileStream.println("</images>"); 

     this.outputFileStream.close(); 
    } 

    @Override 
    public void execute() { 
     validate(); 

     try { 
      openOutputFile(); 

      for (Iterator itFSets = fileSetList.iterator(); itFSets.hasNext();) { 
       FileSet fs = (FileSet) itFSets.next(); 
       DirectoryScanner ds = fs.getDirectoryScanner(getProject()); 
       String[] includedFiles = ds.getIncludedFiles(); 
       for (int i = 0; i < includedFiles.length; i++) { 
        String filename = includedFiles[i]; 

        Dimension dim = getImageDim(ds.getBasedir() + File.separator + filename); 
        if (dim != null) { 
         writeImgToOutputFile(filename, dim); 
        } 
       } 
      } 

      closeOutputFile(); 
     } catch (IOException ex) { 
      log(ex.getMessage()); 
     } 
    } 

    private Dimension getImageDim(final String path) { 
     Dimension result = null; 
     String suffix = this.getFileSuffix(path); 
     Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix(suffix); 
     if (iter.hasNext()) { 
      ImageReader reader = iter.next(); 
      try { 
       ImageInputStream stream = new FileImageInputStream(new File(path)); 
       reader.setInput(stream); 
       int width = reader.getWidth(reader.getMinIndex()); 
       int height = reader.getHeight(reader.getMinIndex()); 
       result = new Dimension(width, height); 
      } catch (IOException e) { 
       log(path + ": " + e.getMessage()); 
      } finally { 
       reader.dispose(); 
      } 
     } 
     return result; 
    } 

    private String getFileSuffix(final String path) { 
     String result = null; 
     if (path != null) { 
      result = ""; 
      if (path.lastIndexOf('.') != -1) { 
       result = path.substring(path.lastIndexOf('.')); 
       if (result.startsWith(".")) { 
        result = result.substring(1); 
       } 
      } 
     } 
     return result; 
    } 
} 
+0

我使用了相同的ant教程來弄清楚如何使用filesets,所以我認爲這兩種實現在這方面都很相似。我對ImageIO瞭解不多,所以我只是將文件讀入BufferedImage並從中獲得了維度。這就是爲什麼我需要設置java.awt.headless - 運行腳本時,我得到了一個java菜單欄。我懷疑你使用的'純粹'ImageIO方法可能會比我的版本快一點,即使代碼有點冗長。無論如何 - 這是一個週日晚上的有趣的小項目。 – matt 2010-11-08 19:49:38

相關問題