Оптимизация загрузки растровых изображений в .Net Compact Framework - PullRequest
0 голосов
/ 01 февраля 2011

Мне нужно загрузить кучу растровых изображений в моем приложении. Проблема в том, что загрузка делает форму очень медленной. Мой настоящий класс выглядит следующим образом:

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; }


}

Цель этого класса - прочитать серию растровых изображений с префиксом [POI], чтобы .net мог отображать легенду в элементе управления формы для изображения poi, отображаемого в окне Sygic Drive .

Вопрос в том, как я могу оптимизировать этот код для более быстрой загрузки изображений. На данный момент он загружает 26 315 тыс. Растровых изображений за 10 секунд. Но, вероятно, в конечном решении мы могли бы получить до +260 изображений, так что это является причиной необходимости оптимизации.

1 Ответ

1 голос
/ 01 февраля 2011

Самое большое потенциальное улучшение, которое я вижу, это то, что PreencherPool загружает все изображения в папку.Вы показываете все изображения одновременно?Если нет, вы можете изменить это, чтобы лениво загружать изображения по требованию или, по крайней мере, загружать их в фоновом потоке, чтобы вызывающая сторона не блокировалась, пока они все загружаются.300k кажется немного большим для «миниатюры» (что и предполагает код).Вы определяете, что вам действительно нужно для диспл15?

...