最近做一個關於圖片展示(類似QQ相冊)的管理軟件,雖然在網上搜到很多有用的資料,但是放到我項目中時,發現很多問題,不能盡善盡美,且很費事。今天終於做完了任務,所以抽點空把我遇到的問題和解決辦法放上來,一是給自己積累經驗,二是可以幫助需要的人。
前提:項目是基於FTP,所以只開放了上傳和下載功能。
任務:將文件夾下圖片文件放入到圖片瀏覽器中。
遇到的問題:
1.Image.Save()發生“GDI中發生一般性錯誤”
2.圖片太大顯示不全的問題
3.刪除文件時報“文件正被另一進程使用”
4.打開非正常圖片,報“內存不足”(類似windows瀏覽器的沒有預覽功能一樣)
解決方案:
1.在打開文件的事件中寫入
Image image = Image.FromFile(filepath);//filepath:圖片路徑
Bitmap bitmap = new System.Drawing.Bitmap(image.Width, image.Height);
//Bitmap bitmap = new Bitmap(image.Width, image.Height, PixelFormat.Format64bppArgb);//打開正常,但圖片保存後就變樣了
Graphics draw = Graphics.FromImage(bitmap);//畫圖
draw.DrawImage(image, 0, 0, image.Width, image.Height);
pictureBox1.Image = (Image)bitmap;
//回收處理
draw.Dispose();
image.Dispose();//釋放文件資源
詳情參見http://www.cnblogs.com/wudingfeng/archive/2008/07/24/1250564.html
2.在圖片顯示的事件中調方法:
(1)//操作PictureBox的位置
ImgLocation();
(2)加入方法:
/// <summary>
/// PictureBox位置-保持在中央
/// </summary>
private void ImgLocation()
{
if (this.pboxImage.Image != null)
{
Point p;
int x_dif = pnlMain.Width - pboxImage.Width;//注:我是將pictureBox放入到名爲pnlMain的panel中
int y_dif = pnlMain.Height - pboxImage.Height;
int x, y = 0;
if (x_dif > 0)
{
x = x_dif / 2;
}
else
{
x = 0;
}
if (y_dif > 0)
{
y = y_dif / 2;
}
else
{
y = 0;
}
p = new Point(x, y);
this.pboxImage.Location = p;
}
}
3.生成圖片文件時注意釋放資源
private void getImageSmall()
{
for (int i = 0; i < ImageManager.imgFileList.Count; i++)
{
Image tempImg = Image.FromFile(ImageManager.imgFileList[i]);//ImageManager.imgFileList[i])存放圖片路徑
Image bmp = new Bitmap(tempImg);
tempImg.Dispose();//注意這句
imageList1.Images.Clear();
this.imageList1.Images.Add(bmp);
PictureBox pbox = new PictureBox();
pbox.SizeMode = PictureBoxSizeMode.Zoom;
pbox.BorderStyle = BorderStyle.FixedSingle;
pbox.Width = 60;
pbox.Height = 60;
pbox.Image = imageList1.Images[0];
pbox.Location = new Point((imageList1.ImageSize.Width+ 3) * i, pnlImage.Location.Y);
pnlImage.Controls.Add(pbox);
}
}
在窗口關閉時加入
pnlImage.Controls.Clear();
try
{
for (int i = 0; i < ImageManager.imgFileList.Count; i++)
{
File.Delete(ImageManager.imgFileList[i]);
}
}
catch
{ }
4.在打開圖片或加載圖片的地方
Image tempImg;
try
{
tempImg = Image.FromFile(filepath);
}
catch
{
tempImg = (Image)getBitmap(width, width);
}
/// <summary>
/// 自定義圖形
/// </summary>
/// <param name="width">圖像寬度</param>
/// <param name="height">高度</param>
/// <returns></returns>
private Bitmap getBitmap(int width, int height)
{
Bitmap bitmap = new Bitmap(width, height);
Graphics draw = Graphics.FromImage(bitmap);
draw.FillRectangle(Brushes.White, this.ClientRectangle);
string addText = "沒有預覽";
System.Drawing.Font font = new Font("宋體", 8);
System.Drawing.Brush brush = new System.Drawing.SolidBrush(Color.Black);
draw.DrawString(addText, font, brush, width / 4, height / 2);
return bitmap;
}
後序擴展(給自己一個總結):
第一個問題:
我最開始用FileStream fs = File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
pboxImage.Image = Image.FromStream(fs, false, true);
fs.Close();
當剛發生這個錯誤時,我用上面網址給出的方法,當圖片保存成功後我很驚訝,於是又找來別的圖片試,結果圖片顯示不出來或顯示出來是灰色的。於是我又修改爲:
Bitmap bmp = new Bitmap(filepath);
Bitmap bmp2 = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format64bppArgb);//保存後圖片周圍都是黑邊
Graphics draw1 = Graphics.FromImage(bmp2);
draw1.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height);
再試,打開沒問題,保存後發現黑邊的問題。最後請來同事幫忙,纔出現了上面的最佳解決方案,唉,終於處理好了。
第二個問題:也是一樣,圖片小沒事,圖片大了以後自動就裁剪了。雖然picturBox有自己的SizeMode,但我的圖片瀏覽器有放大和縮小處理。所以用上面的方案較佳。
第三個問題:
詳細參見http://blog.csdn.net/magily/archive/2010/05/27/5628895.aspx,也就是說要注意方法Image.FromFile時,都釋放引用。
第四個問題:
困繞了我好久,我一直以爲是我電腦緩存或圖片太大的問題,最後才發現原來是圖片非法。鬱悶啊,本來還以爲windows圖片瀏覽器會自動處理,結果並不是這樣,所以堅持纔有勝利,.net加油!