暴风之刃

导航

关于图片的存与读

场合:

在一个详细信息页面中,至少包含一个file控件和一个img控件。在新增时,用file加载一张本地图片,在img里显示,然后保存,将图片存入Oracle表中的Blob字段里;在读取时,读取Blob字段,将图片直接写入img控件,若图片大小过大,则对图片进行压缩。

 

页面部分代码:

    <div align="center" id="div1" runat="server" style="width: 120px; height: 150px;">
        <asp:Image ID="img_ZP" runat="server" Style="width: 120px; height: 150px;" />
    </div>
    <input id="file_PMT" style="width: 220px" onpropertychange="DoShowPicture(this.value,'img_ZP');"
        type="file" name="file_PMT" runat="server">

 

点击file,在img中显示图片的js:

 1     //显示图片
 2     function DoShowPicture(vPicPath, imgName) {
 3         var img;
 4 
 5         if (vPicPath.length < 1) {
 6             return false;
 7         }
 8         img = document.getElementById(imgName);
 9         try {
10             setTimeout(function() { img.src = vPicPath }, 20);
11         }
12         catch (e) {
13         }
14     }

 

图片读入时的验证:

    $(function(){
        $("#img_ZP").on("load",function(){ CheckZJZImg(this); }).error(function(){
            alert("请选择一个图像文件!"); 
            //清除file内容(使用替换的方法)
            var file = $("#file_PMT") ;
            file.after(file.clone().val("")); 
            file.remove();
        });
    });

 

验证方法:

 1     //检测图片
 2     function CheckZJZImg(img) {
 3         var file = $("#file_PMT") ;
 4         if (img.fileSize > (1024 * 100)) {
 5             alert("您选择的图片大小为:" + img.fileSize + "\n注意:大小不能超过100K,请重新选择!");
 6             file.after(file.clone().val("")); 
 7             file.remove(); 
 8             img.src = '';
 9             return false;
10         }
11         if (img.width > 358 || img.height > 441) {
12             alert("您选择的图片宽为:" + img.width + ",高为:" + img.height + "\n注意:尺寸大小不能超过358(宽)X441(高),请重新选择!");
13             file.after(file.clone().val("")); 
14             file.remove();
15             img.src = '';
16             return false;
17         }
18         return true;
19     }

 

验证完毕,就可以保存了,下面是保存方法:

 1             string filename = file_PMT.PostedFile.FileName;
 2             if (filename != "" && "jpg,bmp,png,jpeg,gif".Contains(filename.Substring(filename.LastIndexOf('.') + 1).ToLower()))
 3             {
 4                 int PMTLength = file_PMT.PostedFile.ContentLength;
 5                 byte[] PMTContent = new byte[PMTLength];
 6                 file_PMT.PostedFile.InputStream.Read(PMTContent, 0, PMTLength);
 7                 info.ZP = PMTContent;
 8             }
 9             else
10             {
11                 info.ZP = new byte[0];
12             }
13             //然后把info.ZP传到保存方法里即可

 

 

此处会用到二进制流转化为大对象的方法:

 1         /// <summary>
 2         /// 取得ORACLEBLOB对象
 3         /// </summary>
 4         /// <param name="p_ByteObject">二进制字节数组对象</param>
 5         /// <returns></returns>
 6         protected OracleLob GetOracleBlob( byte[] p_ByteObject )
 7         {
 8             OracleLob    tempLob;
 9             string        cmdText;
10 
11             try
12             {
13                 cmdText = "DECLARE xx blob; BEGIN DBMS_LOB.CREATETEMPORARY";
14                 cmdText += "(xx, false, 0); :tempBlob := xx; END;";
15 
16                 m_Connection.Open();
17 
18                 OracleTransaction tx = m_Connection.BeginTransaction();
19                 OracleCommand oracleCommand = m_Connection.CreateCommand();
20                 oracleCommand.Transaction = tx;
21 
22                 oracleCommand.CommandText = cmdText;
23                 oracleCommand.Parameters.Add(new OracleParameter("tempBlob", OracleType.Blob)).Direction = ParameterDirection.Output;
24 
25                 oracleCommand.ExecuteNonQuery();
26 
27                 tempLob = (OracleLob)oracleCommand.Parameters[0].Value;
28 
29                 tempLob.BeginBatch(OracleLobOpenMode.ReadWrite);
30                 tempLob.Write(p_ByteObject,0,p_ByteObject.Length);
31                 tempLob.EndBatch();
32 
33                 tx.Commit();                
34             }
35             catch(Exception exp)
36             {
37                 throw new AppException(exp.Message, exp);
38             }
39             finally
40             {
41                 m_Connection.Close();
42             }
43 
44             return tempLob;
45         }

 

至此,保存完毕。

 

下面是读取

首先,在读取之前,清空创建的缓存文件夹。因为下面用到的读取方法会在服务器端生成图片,然后将该图片的地址赋给页面的img。所以,如果不清理的话,会使服务器端的图片越来越多。

“../SellerManage/CacheImage/” 这个路径是手动在服务器端创建的
 1         /// <summary>
 2         /// 清理缓存图片
 3         /// </summary>
 4         private void ClearCacheImage()
 5         {
 6             //获取缓存图片文件夹路径
 7             string cacheDocument = Server.MapPath("../SellerManage/CacheImage/");
 8             //若没有,则创建
 9             if (!System.IO.Directory.Exists(cacheDocument))
10             {
11                 System.IO.Directory.CreateDirectory(cacheDocument);
12             }
13             else
14             {
15                 // Search the directory
16                 DirectoryInfo di = new DirectoryInfo(cacheDocument);
17                 //FileInfo[] f = di.GetFiles("*.xls");//文件夹下的.xls文件
18                 FileInfo[] f = di.GetFiles();//文件夹下所有文件
19                 foreach(FileInfo myFile in f)
20                 {
21                     myFile.Delete();
22                 }    
23             }
24         }

 

读取图片:info.ZP是byte[]类型

 1         /// <summary>
 2         /// 读取图片
 3         /// </summary>
 4         private void DoLoadData()
 5         {
 6             ClearCacheImage();  //先清理缓存图片
 7             if (Request.QueryString["rybh"] != null)
 8             {
 9                 this.hidn_rybh.Value = Request.QueryString["rybh"].ToString();
10             }
11             string is_rybh = this.hidn_rybh.Value;
12             SellerInfo info = SellerBAL.GetSellerInfo(is_rybh);
13 
14             if (info.ZP != null && info.ZP.Length != 0)
15             {
16                 MemoryStream stmImageCol = new MemoryStream(info.ZP);
17                 System.Drawing.Image img = System.Drawing.Image.FromStream(stmImageCol);
18                 System.Drawing.Bitmap image = new System.Drawing.Bitmap(img);
19                 string imgname = DateTime.Now.ToString("yyyyMMddhhmmss") + ".jpg";
20                 string path = "../SellerManage/CacheImage/" + imgname;
21                 image.Save(Server.MapPath(path));
22                 //压缩图片
23                 CompressImage(Server.MapPath(path), image, 0);
24                 this.img_ZP.ImageUrl = path;
25             }
26         }

 

压缩图片,是为了使我们读出的图片符合显示规则(例如图片文件大小、质量等等)

 1         /// <summary>
 2         /// 压缩图片
 3         /// </summary>
 4         /// <param name="path">已生产的图片地址</param>
 5         /// <param name="orIMG">从数据库中读取的原图</param>
 6         /// <param name="flag">标识</param>
 7         private void CompressImage(string path, System.Drawing.Bitmap orIMG, int flag)
 8         {
 9             int imgSize = flag == 0 ? 100 : 300; //0:头像 1:身份证扫描件 单位KB
10             
11             FileInfo f = new FileInfo(path);
12             if (f.Length > 1024 * imgSize)
13             {
14                 ImageCodecInfo CodecInfo = GetImageCodecInfo(ImageFormat.Jpeg);
15                 System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters(1);
16                 encoderParams.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 2);
17                 orIMG.Save(path, CodecInfo, encoderParams);
18                 encoderParams.Dispose();
19             }
20         }
21 
22         private ImageCodecInfo GetImageCodecInfo(ImageFormat format)
23         {
24             ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
25             ImageCodecInfo CodecInfo = null;
26             foreach (ImageCodecInfo item in codecs)
27             {
28                 if (item.FormatID == format.Guid)
29                 {
30                     CodecInfo = item;
31                     break;
32                 }
33             }
34             return CodecInfo;
35         }

 

至此,图片显示完毕,在img中显示的是压缩后的图片,js校验的也是压缩后的图片大小。

 

这种读取方式可以用于预览,数据库只保存一张原图,不用保存多张图片。但仅用于单人操作,多人同时操作会删除缓存图片,造成无法读图。此代码有待改进。

posted on 2013-11-01 09:26  暴风之刃  阅读(232)  评论(0)    收藏  举报