2011-02-01 10 views
0

私のアプリケーションでは、たくさんのビットマップを読み込む必要があります。問題は、読み込みがフォームを非常に遅くすることです。次のように私の実際のクラスがある:.Net Compact Frameworkでのビットマップ読み込みの最適化

public class ImagensDisponiveis 
{ 
    /// <summary> 
    /// List of ImagemSygic struct 
    /// </summary> 
    private List<ImagemSygic> _poolImagens; 
    /// <summary> 
    /// index of next avaiable image 
    /// </summary> 
    private int indiceProximoDisponivel; 
    /// <summary> 
    /// Path to image folder 
    /// </summary> 
    private string caminhoPasta; 
    /// <summary> 
    /// Number of found images that conforms to patterm 
    /// </summary> 
    private int MAXCOUNT; 


    public ImagensDisponiveis(string caminhoPastaRecursos) 
    { 
     indiceProximoDisponivel = 0; 
     caminhoPasta = caminhoPastaRecursos; 

     PreencherPool(out _poolImagens, caminhoPasta); 
     MAXCOUNT = _poolImagens.Count; 
    } 

    /// <summary> 
    /// Preenche a lista de imagens com uma estrutura que contém a imagem e o caminho dessa imagem para o Sygic 
    /// </summary> 
    /// <param name="_poolImagens">The _pool imagens.</param> 
    /// <param name="filepath">The filepath.</param> 
    private void PreencherPool(out List<ImagemSygic> _poolImagens, string filepath) 
    { 
     DateTime momentoInicio = DateTime.Now; 
     _poolImagens = new List<ImagemSygic>(); 
     string[] imagens = Directory.GetFiles(filepath); 
#if DEBUG 
     //int counter = 0; 
     //int numFiles = imagens.Length; 
#endif 
     foreach (string caminhoImagem in imagens) 
     { 

      try 
      { 
       string filename = Path.GetFileName(caminhoImagem); 
       //original image to show on .net [POI]anything.bmp 
       //image that sygic tries to use on drive ?[POI]anything.bmp, where ? is an number between 1 to 6 
       bool valido = filename.StartsWith("[POI]", StringComparison.InvariantCulture); 
       //Log.writeToLog(caminhoImagem + " " + valido.ToString()); 
       if (valido) 
       { 

        var streamImagem = File.Open(caminhoImagem, FileMode.Open, FileAccess.Read); 
        Bitmap temImagem = new Bitmap(streamImagem); 
        ImagemSygic tempImgSygic = new ImagemSygic(); 
        tempImgSygic.CaminhoImagemSygic = caminhoImagem; 
        tempImgSygic.ImagemWindows = temImagem; 
        tempImgSygic.SygicImageID = -1; 
        _poolImagens.Add(tempImgSygic); 
#if DEBUG 
        //counter++; 

#endif 
       } 
      } 
      catch (ArgumentException aec) 
      { 
       Log.writeToLog("[EXCEPCAO ImagensDisp]: ArgumentException - " + aec.Message); 
      } 
      catch (UnauthorizedAccessException uae) 
      { 
       Log.writeToLog("[EXCEPCAO ImagensDisp]: UnauthorizedAccessException - " + uae.Message); 
      } 

      catch (Exception exc) 
      { 
       Log.writeToLog("[EXCEPCAO ImagensDisp]: Exception - " + exc.Message); 
      } 
     } 

     DateTime tempoFim = DateTime.Now; 

     TimeSpan duracao = tempoFim.Subtract(momentoInicio); 
     Log.writeToLog("[Criacao da pool] Demorou " + duracao.TotalSeconds.ToString()); 
    } 
    /// <summary> 
    /// OObtains the next avaianle ImagemSygic if there is an avaiable 
    /// </summary> 
    /// <returns>ImagemSygic if possible, else null</returns> 
    public ImagemSygic ObterProximoDisponivel() 
    { 
     if (indiceProximoDisponivel > MAXCOUNT) 
      return null; 
     else 
     { 
      ImagemSygic imagemRetornar = _poolImagens[indiceProximoDisponivel]; 
      indiceProximoDisponivel++; 
      return imagemRetornar; 
     } 
    } 

    public void ResetCounter() 
    { 
     indiceProximoDisponivel = 0; 
    } 


} 

/// <summary> 
/// Class that contains the Bitmap preview and the original path to that image 
/// </summary> 
public class ImagemSygic 
{ 

    private volatile int _imageID; 
    /// <summary> 
    /// Gets or sets the imagem windows. 
    /// </summary> 
    /// <value>The imagem windows.</value> 
    public Bitmap ImagemWindows { get; set; } 
    /// <summary> 
    /// Gets or sets the caminho imagem sygic. 
    /// </summary> 
    /// <value>The caminho imagem sygic.</value> 
    public string CaminhoImagemSygic { get; set; } 

    /// <summary> 
    /// Gets or sets the sygic image ID. 
    /// </summary> 
    /// <value>The sygic image ID.</value> 
    public int SygicImageID 
    { 
     get 
     { 
      return this._imageID; 
     } 
     set 
     { 
      this._imageID = value; 
     } 
    } 
} 

/// <summary> 
/// 
/// </summary> 
public class POISygic 
{ 

    private volatile int _latitude; 
    private volatile int _longitude; 
    /// <summary> 
    /// Gets or sets the imagem. 
    /// </summary> 
    /// <value>The imagem.</value> 
    public ImagemSygic Imagem { get; set; } 
    /// <summary> 
    /// Gets or sets the latitude. 
    /// </summary> 
    /// <value>The latitude.</value> 
    public int Latitude { get { return this._latitude; } set { this._latitude = value; } } 
    /// <summary> 
    /// Gets or sets the longitude. 
    /// </summary> 
    /// <value>The longitude.</value> 
    public int Longitude { get { return this._longitude; } set { this._longitude = value; } } 
    /// <summary> 
    /// Gets or sets the descricao. 
    /// </summary> 
    /// <value>The descricao.</value> 
    public string Descricao { get; set; } 

    /// <summary> 
    /// Gets or sets a value indicating whether this instance is displayed now. 
    /// </summary> 
    /// <value> 
    ///  <c>true</c> if this instance is displayed now; otherwise, <c>false</c>. 
    /// </value> 
    public bool isDisplayedNow { get; set; } 

    /// <summary> 
    /// Gets or sets the elem ID. 
    /// </summary> 
    /// <value>The elem ID.</value> 
    public int elemID { get; set; } 


} 

このクラスの目的は、.NETが現れるポイ画像にフォームコントロールで凡例を表示できるように[POI]接頭辞を有するビットマップのセリエを読み取ることですSygic Driveウィンドウに表示されます。

質問は、このコードを最適化してイメージを高速に読み込む方法です。現時点では、10秒で26個の315kビットマップイメージがロードされます。しかしおそらく最終的な解決策では、最大で+260個の画像を持つことができるため、最適化が必要です。

+0

お元気ですか?私たちは英語でそれを使うことができますか?私はgoogleに行きます翻訳... ...しかし.. –

+0

@Shekhar_Pro完了、申し訳ありませんが、私の会社はポルトガル語ですので、ポルトガル語のもの – Sorcerer86pt

答えて

1

私が見る最大の潜在的な改善は、PreencherPoolがフォルダ内のすべての画像を読み込むことです。一度にすべての画像を表示していますか?そうでなければ、必要に応じて画像を遅延ロードするか、少なくともバックグラウンドスレッドにロードして、呼び出し元がすべてロードされている間にブロックしないようにすることができます。

私はまた、300kが "サムネイル"(コードが示唆しているもの)のために少し大きいように思われます。あなたは実際にdispl15のためにそれをサイジングしていますか?

+0

サイズは24 * 32px 32ビットARGBイメージに固定されています。そしてフォーマットはその方​​法です。なぜなら、sygicドライブが使用するものですから。どうやってそれをやり遂げることができますか? – Sorcerer86pt

+0

24x32x32bppはわずか3k(24ピクセル* 32ピクセル* 4バイト/ピクセル)なので、報告する内容には2倍の差異があります。遅延読み込みの場合、コンシューマがImageを呼び出してその時点でロードしてキャッシュすると、最初の呼び出しでロードされ、その後の呼び出しでキャッシュされたバージョンが取得されるように、すべてのイメージをすぐに読み込まないでください。 – ctacke

関連する問題