我需要在我的应用程序中加载一堆位图。问题是加载使表单非常慢。我的实际课程如下:
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在窗体控件中显示一个图例,显示在Sygic Drive窗口中显示的poi图像。
问题是如何优化此代码以更快地加载图像。目前它在10秒内加载26个315k位图图像。但可能在最终的解决方案中,我们可以拥有多达+260个图像,因此这就是需要优化的原因。
答案 0 :(得分:1)
我看到的最大潜在改进是PreencherPool
加载文件夹中的所有图像。你是否一次显示所有图像?如果没有,您可以根据需要将其更改为延迟加载图像,或者至少将它们加载到后台线程中,以便调用者在加载时不会阻塞。
我还建议300k似乎有点大“缩略图”(代码表明它们是)。您是否正在根据您的实际需要调整它?