最近做一个关于图片展示(类似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加油!