キャッシュタイルの最適化


ArcGIS for Server 10.1で「PNG」を指定してキャッシュを生成するとアルファ付32bit PNGとなる。
見栄えと軽さのバランス的にはJPEGがベストだが透過しない。

8bit PNGを指定して作らせると何やら荒く見える。

とりあえず最適化系のソフトにかけてみた。
http://pngquant.org/

見栄えは悪くなさそう?
Google Mapsも8bitなので出来るだけ軽くはしたいのだが…。

検討課題
コンパクトキャッシュ ( .bundle )ではかけれない。
MBTile的なSQLiteファイルをキャッシュ配信する仕組みが欲しい。
なんせ、ArcSOC経由でデータ参照するような仕組みはいらないし、背景のみで十分なので
エクスプロードで作成しておいて、圧縮 SQLiteにぶち込み自分配信した方が良いのではないかと。
(コンパクトよりコンパクトになりそうだし、仕組みが単純なので堅牢そう)

最適化すると以下のようになる。

ファイル数 実バイト 実MB 1ファイルあたりKB
52631 151,139,942 144 2.8
圧縮 52631 50,453,262 48 0.9

ファイル数多いとバックアップも変換・移動も大変だが、エクスプロードで運用しているならばおすすめかも。

変換 ( 自動実行? ) 方法は詳細


以下のような引数実行で置換可能
pngquant –force –ext .png –quality=50-90 対象の画像.png

もろもろ設定ファイルと引数にして以下のように実行 (コンソールアプリ)

  public class Helper
  {
    private string _appPath = null;
    private string _baseArgs = null;
    private bool _useShell = true;
    private bool _noWindow = false;

    private int _count = 0;
    private int _left = int.MinValue;
    private int _top = int.MinValue;

    public Helper()
    {
      this._appPath = ConfigurationManager.AppSettings["AppPath"];
      this._baseArgs = ConfigurationManager.AppSettings["BaseArgs"];

      bool.TryParse(ConfigurationManager.AppSettings["NoWindow"], out this._noWindow);
      bool.TryParse(ConfigurationManager.AppSettings["UseShell"], out this._useShell);

      if (!File.Exists(this._appPath))
        throw new FileNotFoundException("pngquantがありません。");

      this._top = Console.CursorTop;
      this._left = Console.CursorLeft;

    }//end method

    public void Convert(string baseDir)
    {
      if (!Directory.Exists(baseDir))
        throw new DirectoryNotFoundException(baseDir + "が存在しません");

      Queue q = new Queue();
      q.Enqueue(baseDir);

      while (q.Count > 0)
      {

        string d = (string)q.Dequeue();

        string[] files = Directory.GetFiles(d);
        foreach (string file in files)
        {

          FileInfo f = new FileInfo(file);
          if (f.Extension != ".png")
            continue;

          this.startProcess(f);
        }//end loop

        string[] dirs = Directory.GetDirectories(d);
        foreach (string s in dirs)
        {
          q.Enqueue(s);
        }//end loop
      }
    }//end method

    private void startProcess(FileInfo f)
    {
      ProcessStartInfo info = new ProcessStartInfo();
      info.FileName = this._appPath;
      info.Arguments = this._baseArgs + " " + f.FullName;
      info.CreateNoWindow = this._noWindow;
      info.UseShellExecute = this._useShell;

      Process p = Process.Start(info);
      p.WaitForExit();

      this._count++;

      Console.SetCursorPosition(this._left, this._top);
      Console.Write("{0}ファイル",this._count);
    }

  }//end class

設定ファイル例

    <add key="AppPath" value="C:\tools\pngquant\pngquant.exe"/>
    <add key="BaseArgs" value=" --force --quality=50-90 "/>
    <add key="NoWindow" value="False"/>
    <add key="UseShell" value="True"/>
カテゴリー: 運用, 設計 タグ: パーマリンク