图片打开,保存,浏览

来源:互联网 发布:周朝文化知乎 编辑:程序博客网 时间:2024/05/01 03:39

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

原创粉丝点击