在.Net精简版框架中优化位图加载
问题描述:
我需要在我的应用程序中加载一堆位图。问题是加载使表单非常慢。我的实际的类如下:在.Net精简版框架中优化位图加载
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窗口中。
问题是我如何优化这段代码来加载图像更快。目前它在10秒内加载26个315k位图图像。但可能在最终的解决方案中,我们可以有多达260个图像,所以这是需要优化的原因。
答
我看到的最大潜在改进是PreencherPool
加载文件夹中的所有图像。你是否一次显示所有图像?如果没有,你可以改变它懒惰加载图像按需,或至少加载他们在后台线程,所以调用者不会阻止,而他们都加载。
我也建议300k似乎有点大“缩略图”(代码表明他们是)。您是否根据您实际需要的displ15来调整它?
哇......这是什么..我们可以用英文请它..好吧我要去谷歌翻译...但.. – 2011-02-01 11:24:28
@Shekhar_Pro完成,抱歉,但因为我的公司是葡萄牙语,我们对重要的评论事情在葡萄牙语 – Sorcerer86pt 2011-02-01 12:12:31