摘 要: 通過對數(shù)據(jù)庫如何存取圖片的研究,提出在.Net平臺下基于Web的SQL Server數(shù)據(jù)庫存取圖片的優(yōu)化算法,該算法能有效優(yōu)化圖片大小,節(jié)省數(shù)據(jù)庫容量,不占用服務(wù)器空間,減少服務(wù)器的響應(yīng)時(shí)間,提高網(wǎng)頁中的圖片加載速度。
關(guān)鍵詞: 數(shù)據(jù)庫; 優(yōu)化圖片; 存取圖片; 網(wǎng)頁打開速度;數(shù)據(jù)庫容量
互聯(lián)網(wǎng)上幾乎所有網(wǎng)頁都由圖片和文字組成,許多大型網(wǎng)站都涉及圖片管理功能的實(shí)現(xiàn)。在網(wǎng)絡(luò)環(huán)境中,由于圖片文件相對較小,因此比音頻和視頻文件更加便于傳輸。在很多應(yīng)用領(lǐng)域中出現(xiàn)了對專用的網(wǎng)絡(luò)環(huán)境下圖片數(shù)據(jù)庫的需求,即利用數(shù)據(jù)庫平臺實(shí)現(xiàn)圖片大量的集中存儲,同時(shí)以網(wǎng)絡(luò)為連接,通過基于HTTP協(xié)議的網(wǎng)絡(luò)瀏覽器實(shí)現(xiàn)對數(shù)據(jù)庫(包括圖片數(shù)據(jù))的遠(yuǎn)程訪問[1]。
網(wǎng)頁中圖片的加載速度直接影響該網(wǎng)頁打開速度。訪問者認(rèn)為,打開速度較快的網(wǎng)站質(zhì)量更高、更可信、也更有趣;網(wǎng)頁打開速度越慢,訪問者的心理挫折感就越強(qiáng),就會對網(wǎng)站的可信性和質(zhì)量產(chǎn)生懷疑。
基于以上情況,如何有效提高網(wǎng)站頁面打開速度,是每個(gè)網(wǎng)站管理者和開發(fā)人員非常關(guān)注和必須解決的問題。本文通過對數(shù)據(jù)庫如何存取圖片的研究,提出了一種優(yōu)化算法。
1 圖片存取的方法分析
目前網(wǎng)頁上的圖片存儲一般有兩種方法:
(1)將圖片以獨(dú)立文件的形式存放至服務(wù)器中,同時(shí)在數(shù)據(jù)庫對應(yīng)表中的文本類型字段中存放該圖片的文件路徑[2]。這種方法具有縮小數(shù)據(jù)表,提高數(shù)據(jù)庫相關(guān)操作速度且容易編程實(shí)現(xiàn)的優(yōu)點(diǎn),但是卻造成了圖片及其描述信息的分離,如果數(shù)據(jù)過期或不用而刪掉,對應(yīng)圖片沒有刪掉,仍占著服務(wù)器空間[1]。
(2)將圖片直接放入數(shù)據(jù)庫對應(yīng)表的image數(shù)據(jù)類型字段中,使得圖片和數(shù)據(jù)描述成為一個(gè)整體[3]。這種方法存放的圖片格式很靈活,管理很方便,而且安全性也很好,最重要的是,如果過期或不用的數(shù)據(jù)刪掉,對應(yīng)的所有圖片及相關(guān)信息也都刪掉,不再占用服務(wù)空間。但是如果圖片越大,占用數(shù)據(jù)庫存儲空間也越大,網(wǎng)頁打開加載圖片也就越慢[1]。
在目前的研究中,采用第二種方法存取圖片時(shí),基于移動設(shè)置優(yōu)化PNG圖片,在PNG圖片的數(shù)據(jù)結(jié)構(gòu)中,部分?jǐn)?shù)據(jù)塊是可選的,剔除可選數(shù)據(jù)段,對PNG進(jìn)行適當(dāng)?shù)奶幚?,可以有效減少占用空間,優(yōu)化移動設(shè)備上的圖片應(yīng)用。圖片處理前后的大小相差很多,結(jié)果很不穩(wěn)定[4]。
本文采用第二種存取圖片的方法,針對圖片占用數(shù)據(jù)庫存儲空間過大、網(wǎng)頁加載圖片過慢的問題,提出了優(yōu)化圖片算法。
2 建數(shù)據(jù)庫建表
本實(shí)驗(yàn)采用轉(zhuǎn)換為二進(jìn)制的方式將圖片文件的全部數(shù)據(jù)存儲到image[5-6]字段中,使用時(shí)再通過特定的過程將二進(jìn)制信息轉(zhuǎn)換成原來格式的文件內(nèi)容,從而真正地實(shí)現(xiàn)數(shù)據(jù)的整體存儲,避免了平臺更換和數(shù)據(jù)移植時(shí)可能帶來的記錄失效問題。
(1)在數(shù)據(jù)庫SQL 2005中建立testimgbig和testimgsmall兩個(gè)數(shù)據(jù)庫;
(2)在兩個(gè)數(shù)據(jù)庫中分別建表imgbig和imgsmall,如表1和表2所示;
(3)分別在兩個(gè)數(shù)據(jù)庫中建立Addimgbig和Addimgsmall兩個(gè)存儲過程。
3 實(shí)驗(yàn)過程
本實(shí)驗(yàn)采用C#編程語言,Visual Studio 2005開發(fā)工具,Microsoft SQL Server 2005數(shù)據(jù)庫以及IIS5.0,在服務(wù)器的網(wǎng)站根目錄下建立“tmpimages”及兩個(gè)子文件夾“img1”和“img2”。
3.1數(shù)據(jù)庫存取圖片流程
(1)未優(yōu)化圖片存入數(shù)據(jù)庫流程。將本地圖片上傳到服務(wù)器“tmpimages/ img1”文件夾下,在服務(wù)器端將上傳的圖片轉(zhuǎn)化為字符流存入數(shù)據(jù)庫;
(2)優(yōu)化圖片存入數(shù)據(jù)庫流程。本地圖片上傳到服務(wù)器“tmpimages/ img1”文件夾下,在服務(wù)器端將上傳的圖片進(jìn)行優(yōu)化處理,然后將圖片存到服務(wù)器“tmpimages/ img2”文件夾下,同時(shí)將“img2”中剛優(yōu)化的圖片轉(zhuǎn)化為字符流存入數(shù)據(jù)庫;
(3)讀取圖片流程。連接圖片所在數(shù)據(jù)庫,找到此圖片表名及字段,然后將對應(yīng)圖片ID號的字符流轉(zhuǎn)化為可視圖片。
3.2相關(guān)核心代碼
(1)將圖片存入數(shù)據(jù)庫的相關(guān)核心代碼
SqlConnection conn=new SqlConnection//連接數(shù)據(jù)庫;
SqlCommand cmd=conn.CreateCommand();
cmd.CommandType=CommandType.StoredProcedure;
//調(diào)用存儲過程
cmd.CommandText="Addimgbig";
string fullfileName=this.FileUpload1 .FileName;
//獲取路徑名
if(fullfileName.Trim().Length !=0)//路徑名不能為空
{
string typebig=fullfileName.Substring(fullfileName.
LastIndexOf(".")+1);
Random rad=new Random();
string RanNum=Convert.ToString(rad.Next());
//獲取隨機(jī)數(shù)
string dt=年月日時(shí)分秒+6位隨機(jī)數(shù);
//防止圖片重名,給圖片重命名
string fileName = "";
if (fullfileName != "")//為了防止用戶
不添加圖片時(shí),保存文件的語句出現(xiàn)問題
{
fileName=dt+fullfileName.Substring(fullfileName.LastIndexOf("."));//獲取圖片名稱
}
string url1=@"tmpimages\\img1"+"\\"+fileName;
//定數(shù)據(jù)庫中字段url
if(typebig !="")
{
this.FileUpload1 .SaveAs(Server.MapPath("tmpimages
\\img1")+"\\"+fileName);
pathNamebig1=Server.MapPath(url1);
System.IO.FileStream fs=new System.IO.FileStream
(pathNamebig1,System.IO.FileMode.Open);
byte[]imagebig=new byte[fs.Length];
BinaryReader br=new BinaryReader(fs);
imagebig=br.ReadBytes(Convert.ToInt32(fs.Length));
cmd.Parameters.AddWithValue("@imgbig", imagebig);
}
}
conn.Open();//打開數(shù)據(jù)庫
cmd.ExecuteNonQuery();//執(zhí)行數(shù)據(jù)庫
conn.Close();//關(guān)閉數(shù)據(jù)庫
(2)優(yōu)化圖片的相關(guān)核心代碼
System.Drawing.Image originalImage=
System.Drawing.Image.FromFile(filePath);
int ow=originalImage.Width;
int oh=originalImage.Height;
int towidth=220;
int toheight=220;//定義優(yōu)化圖片寬高
也可以只定義寬或高,動態(tài)按比例縮小
//從文件取得圖片對象
System.Drawing.Image image=System.Drawing.Image.
FromFile(filePath, true);
//取得圖片大小
System.Drawing.Size size=new System.Drawing.
Size((int)image.Width,(int)image.Height);
//新建一個(gè)bmp圖片
System.Drawing.Image bitmap=new System.Drawing.Bitmap(towidth,toheight);System.Drawing.Graphics g=System.Drawing.Graphics.FromImage(bitmap); //新建一個(gè)畫板
//設(shè)置高質(zhì)量插值法
g.InterpolationMode=System.Drawing.Drawing2D.InterpolationMode.Default;
//設(shè)置高質(zhì)量,低速度呈現(xiàn)平滑程度
g.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.Default;
g.Clear(System.Drawing.Color.White); //清空一下畫布
//在指定位置畫圖
g.DrawImage(image,new System.Drawing.Rectangle(0,0,bitmap.Width,bitmap.Height),new System.Drawing.Rectangle(0, 0,image.Width,image.Height),System.Drawing.GraphicsUnit.Pixel);
if(File.Exists(saveImg))File.Delete(saveImg);//刪除已有文件
//保存高清晰度的縮略圖
bitmap.Save(saveImg.ToString(),System.Drawing.Imaging.ImageFormat.Jpeg);
g.Dispose();
image.Dispose();
bitmap.Dispose();
(3)讀取圖片的相關(guān)核心代碼
SqlConnection conn=new SqlConnection();//連接數(shù)據(jù)庫
string sql="select imgbig from imgbig where id=′"+ imgid+"′";
SqlCommand command=new SqlCommand(sql,conn);
conn.Open();//打開數(shù)據(jù)庫
SqlDataReader dr=command.ExecuteReader();
while(dr.Read())
{
Response.BinaryWrite((byte[])dr[0]);//讀取數(shù)據(jù)流
}
Response.Write("");
conn.Close();//關(guān)閉數(shù)據(jù)庫
4 實(shí)驗(yàn)數(shù)據(jù)
頁面加載時(shí)間測試方法:用秒表在本地機(jī)上測試。測試未優(yōu)化和優(yōu)化后各20次,去掉差距較大的4個(gè),然后取平均數(shù)。
圖片選用使用數(shù)碼相機(jī)拍攝的未處理的圖片(主要是為了更容易測試算法有效性),上傳的所有圖片都是同一張圖片,以便于比較。
進(jìn)行數(shù)據(jù)庫備份。當(dāng)備份到1、10、20張圖片時(shí),分別備份一次。
實(shí)驗(yàn)結(jié)果如表3所示,部分?jǐn)?shù)據(jù)如圖1~圖4所示,測試頁面如圖5所示。
在測試頁面中,未優(yōu)化圖片和優(yōu)化圖片的顯示從視覺上效果一樣,并沒有出現(xiàn)因?yàn)閴嚎s而丟失像素模糊現(xiàn)象。
由以上數(shù)據(jù)可以看出,本文提出的存取圖片優(yōu)化算法是一種有效的圖片壓縮、優(yōu)化方法,同時(shí)能節(jié)省數(shù)據(jù)庫容量,明顯提高了網(wǎng)頁加載圖片速度。在服務(wù)器的“img1”和“img2”文件夾中的圖片可以定期刪除掉,不占用服務(wù)器空間。
本文測試是在本機(jī)上進(jìn)行的,用了同一張?jiān)瓐D片測試,明顯看出頁面加載時(shí)間的差距和數(shù)據(jù)庫的容量。大型網(wǎng)站有更多圖片,如果采用優(yōu)化算法,將大大減少頁面加載時(shí)間和數(shù)據(jù)庫容量,同時(shí)不占用服務(wù)器空間,有效提高網(wǎng)頁打開速度。
本算法在基于Web網(wǎng)站開發(fā)中對圖片處理具有很高的實(shí)用價(jià)值,用C#、Java語言開發(fā)網(wǎng)站都可以借鑒此算法。本文只是在本機(jī)上用該算法對少量圖片進(jìn)行測試,當(dāng)有大數(shù)據(jù)量時(shí),該算法效果將更加明顯。雖然圖片的像素降低從視覺效果上差別不大,但如果對圖像精確度要求特別高還有待考慮,該算法還有待不斷改進(jìn)和優(yōu)化。
參考文獻(xiàn)
[1] 李偉民,何偉,李平.基于Web的SQLServer數(shù)據(jù)庫存取圖片的Delphi實(shí)現(xiàn)[J].計(jì)算機(jī)工程與設(shè)計(jì),2007,28(12):2943-2945.
[2] 戰(zhàn)仁軍,張明書.圖像文件在數(shù)據(jù)庫中的存取[J].西安工程科技學(xué)院學(xué)報(bào),2003,17(4):369-372.
[3] 張永仁,黃科軍,李德孝.基于數(shù)據(jù)庫的文件管理[J].計(jì)算機(jī)工程與設(shè)計(jì),2006,27(11):2044-2045.
[4] 徐逸卿,劉林.基于移動設(shè)備的PNG圖片優(yōu)化實(shí)現(xiàn)[J].多媒體技術(shù)及應(yīng)用,2008,3(9):2070-2075.
[5] 郭東青,李佳,劉彬彬.數(shù)據(jù)庫創(chuàng)建、數(shù)據(jù)倉庫與優(yōu)化[M].北京:清華大學(xué)出版社,2001.
[6] 古凌風(fēng).用ADO技術(shù)實(shí)現(xiàn)數(shù)據(jù)庫圖像字段的存取[J].計(jì)算機(jī)工程與設(shè)計(jì),2004,25(8):1388-1392.