在做網站的時候,我們通常把圖片文件以文件路徑的形式存儲在數據庫。但是做移動開發的時候,這種方式是不可取的,你想想,別人下載了你的軟件後,下載的時你的文件路徑。或者你如果把圖片之間存儲在移動終端,那將佔多大的內存----一個佔內存的流氓軟件。 即使用戶願意下載大量的圖片。如果你的服務器更新了,那麼用戶讀取的將只是圖片的路徑,出來不了圖片的。
所以做移動開發的時候,一定要把圖片通過二進制流的形式存儲在數據庫。
我們今天講的是windows phone 8 通過wcf服務和sql數據庫存儲二進制流信息。
先說下wcf端的配置,在 <system.serviceModel>下添加<bind
<bindings>
<!--<wsHttpBinding>-->
<basicHttpBinding>
<binding sendTimeout="00:10:00" transferMode="Streamed" messageEncoding="Text" textEncoding="utf-8" maxReceivedMessageSize="9223372036854775807" maxBufferPoolSize="2147483647" >
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
<!--</wsHttpBinding>-->
</bindings>
修改<system.web>
配置如下
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" maxRequestLength="102400"/>
</system.web>
第一步:
首先你應該通過選擇器獲取數據流。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
//引入命名空間
using System.Windows.Media.Imaging;
using Microsoft.Phone.Tasks;
using System.IO;
{
public partial class UpGood : PhoneApplicationPage
{
byte[] GoodPhoto;
//相機選擇器
CameraCaptureTask MyCamera = new CameraCaptureTask();
//本地照片選擇器
PhotoChooserTask ptc = new PhotoChooserTask();
public UpGood()
{
InitializeComponent();
// 第二步,在頁面構造函數中註冊完成回調事件
MyCamera.Completed += new EventHandler<PhotoResult>(MyCamera_Completed);
ptc.Completed += new EventHandler<PhotoResult>(ptc_Completed);
}
private void btnCamera_Click(object sender, RoutedEventArgs e)
{
// 第三步,顯示組件
MyCamera.Show();
}
// 第四步,處理事返回結果
public void MyCamera_Completed(object sender, PhotoResult e)
{
//把事件處理結果的Stream轉化成二進制
byte[] GoodPhoto = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Read(GoodPhoto, 0, (int)e.ChosenPhoto.Length);
//在客戶端及時顯示選擇器選擇的圖片
if (e.TaskResult == TaskResult.OK)
{
// 從返回的流中創建圖象
Stream stream=e.ChosenPhoto;
BitmapImage bmp = new BitmapImage();
try
{
bmp.SetSource(e.ChosenPhoto);
// 把圖象作爲Image控件的源。
// 防止異步回調直接訪問UI元素,故應使用BeginInvoke方法。
Dispatcher.BeginInvoke(() =>
{
this.img.Source = bmp;
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
//處理選擇本地照片
void ptc_Completed(object sender, PhotoResult e)
{
byte[] GoodPhoto = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Read(GoodPhoto, 0, (int)e.ChosenPhoto.Length);
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
try
{
bmp.SetSource(e.ChosenPhoto);
Dispatcher.BeginInvoke(() => {
this.img.Source = bmp;
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private void btnShow_Click(object sender, RoutedEventArgs e)
{
ptc.Show();
}
點擊上傳按鈕
<span style="font-size:14px;"> private void UpGoods_Click(object sender, EventArgs e)
{
String GoodName=txtGoodName.Text.Tostring();
//將信息傳到數據庫
ServiceReference1.Service1Client saveGood = new ServiceReference1.Service1Client();
saveGood.SaveGoodInfoCompleted += new EventHandler<ServiceReference1.SaveGoodInfoCompletedEventArgs>(saveGood_SaveGoodInfoCompleted);
saveGood.SaveGoodInfoAsync(GoodName,GoodPhoto );
}
private void saveGood_SaveGoodInfoCompleted(object sender, ServiceReference1.SaveGoodInfoCompletedEventArgs e)
{
if (e.Result == true)
{
MessageBox.Show("添加成功");
}
else
{
MessageBox.Show("添加失敗!");
}
}
}
}</span>
//第二部,在wcf端接收wp端傳進來的GoodName, GoodPrice, StudentName, GoodType, GoodDetail, GoodPhoto, DateTime, GPhone字段,將所有字段存入數據庫
//根據wp 傳過來的流,將流存入數據庫
<span style="font-size:14px;"> public bool SaveGoodInfo(string GoodName, byte[] GoodPhoto)
{
DBHelper db = new DBHelper();
SqlConnection cnn = db.ConnectionCnnString1;
string sql = "insert into Goods(GoodName ,GoodPhoto ) values('" + GoodName + "','" + GoodPhoto + "')";
int i = db.AddTable(sql);
if (i == 1)
{ //插入成功數據
return true;
}
else
{ //插入失敗
return false;
}
</span>
}
//到此整個存儲數據成功,那我們現在把圖片讀取出來啦
//在wp端,我們傳進來StudentName
<span style="font-size:14px;">protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string StudentName =txtStudentName.Text.Tostring();
//這裏還要根據用戶的名字 ,查找用戶的頭像
ServiceReference1.Service1Client Stuph = new ServiceReference1.Service1Client();
Stuph.returnPhotoCompleted+= new EventHandler<ServiceReference1.returnPhotoCompletedEventArgs> (Stuph_returnPhotoCompleted);
Stuph.returnPhotoAsync(StudentName);
}
}
private void Stuph_returnPhotoCompleted(object sender,ServiceReference1.returnPhotoCompletedEventArgs e)
{
//這裏根據從wcf端返回的二進制流信息,生成一張圖片,在前臺的Image控件上顯示。這裏主意要 //添加
// using System.Windows.Media.Imaging;
// using System.IO; 引用
MemoryStream ms = new MemoryStream(e.Result);
BitmapImage bi = new BitmapImage();
bi.SetSource(ms);
image.Source = bi;
}</span>
在wcf端從數據庫中讀取二進制流並返回調用他的wp端
//根據傳過來的用戶名,查找是用的頭像,返回頭像的字符串
public byte[] returnPhoto(string StudentName)
{
byte[] StudentPhoto = null;
DBHelper db = new DBHelper();
SqlConnection cnn = db.ConnectionCnnString1;
string sql = "select StudentPhoto from Student where StudentName='" + StudentName + "'";
SqlCommand cmd = new SqlCommand();
cmd.Connection = cnn;
cmd.CommandText = sql;
byte[] bt = (byte[])cmd.ExecuteScalar();
cnn.Close();
return bt;
}
這裏注意一點,在模擬機上測試是無效的。要在真機上測試。