关于图片用二进制存储
——蔷薇
1. 目的:将图片存储进SQL2000数据库,利用二进制来进行存储,数据库中的字段利用image类型;
2. 具体的操作:首先后台必须能够添加图片,然后转换成二进制保存进数据库,最后就是能够将图片进行显示
3. 显示图片:
string ConnStr = ConfigurationSettings.AppSettings["connstr"];//get the connectString
string strSql = "select top 1 * from myimage";//the sql string where to find the image from the database
SqlConnection conn = new SqlConnection(ConnStr);//connect to the sqldatabse
conn.Open();//open the database
SqlCommand cmd = new SqlCommand(strSql, conn);//the sql command
SqlDataReader reader = cmd.ExecuteReader();//do it
while (reader.Read())
{
Response.ContentType = "application/octet-stream";
Response.BinaryWrite((Byte[])reader["kelly"]);
Response.Write("successful");
}
reader.Close();
conn.Close();
Response.End();
利用实体类来显示图片:生成实体类model和Opt
myimage image = new myimage();//Entity.Model.XXX
myimage_Opt imageopt = new myimage_Opt();//the option of the model
image=imageopt.GetModel(5);//get the instance of the model
Response.BinaryWrite((Byte[])image.kelly);
Response.End();
在利用实体类的时候,必须注意的就是必须修改数据的存储类型,在SQL里面进行存储的时候,自动生成的是string,然后必须修改为model.kelly = ds.Tables[0].Rows[0]["kelly"] as byte[];在model和option必须都进行修改该才能够进行显示
4. 存储图片
myimage image = new myimage();
myimage_Opt imageopt = new myimage_Opt();//get the model and the entity
string strPath = UpPhoto.PostedFile.FileName.ToString();//get the imagePath
HttpPostedFile upPhoto = UpPhoto.PostedFile;
int upPhotoLength = upPhoto.ContentLength;//get the size
FileStream fs = File.OpenRead(strPath);//to the stream of the pic
byte[] PhotoArray = new Byte[upPhotoLength];
fs.Read(PhotoArray, 0, PhotoArray.Length);
image.kelly = PhotoArray;
image.name = "nothing was complete";
imageopt.Add(image);
在使用实体类的时候,在Add方法中必须修改参数的名称
SqlParameter[] parameters = {
new SqlParameter("@kelly", SqlDbType.Image,model.kelly.Length),
new SqlParameter("@name", SqlDbType.VarChar,50)};
图片的格式必须修改为image类型,并且大小必须修改为二进制的大小,否则会出现截断的现象,从而导致图片不能够正常的读出
5. 当不使用实体类来进行存储图片的方法
//好像是二进制的方法存入数据库,
//获得图象并把图象转换为byte[]
HttpPostedFile upPhoto = UpPhoto.PostedFile;//组件的名称,获得图片的路径
int upPhotoLength = upPhoto.ContentLength;
byte[] PhotoArray = new Byte[upPhotoLength];
Stream PhotoStream = upPhoto.InputStream;
PhotoStream.Read(PhotoArray, 0, upPhotoLength);
//连接数据库
string connectionString = ConfigurationSettings.AppSettings["connstr"];//get the connectString
SqlConnection conn = new SqlConnection(connectionString);
string strSql = "Insert into myimage(kelly,name) values(@pic,'name')";
SqlCommand cmd = new SqlCommand(strSql, conn);
cmd.Parameters.Add("@pic", SqlDbType.Image);
cmd.Parameters["@pic"].Value = PhotoArray;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
另外的一种使用SQL直接进行存储图片的方法,不会进行其他的修改
//用流的方法存储进入数据库
string strPath = string.Empty;
strPath = UpPhoto.PostedFile.FileName.ToString();
FileStream fs = File.OpenRead(strPath);
byte[] imageb=new byte[fs.Length];
fs.Read(imageb, 0, imageb.Length);
fs.Close();
string sql = "insert into myimage (kelly) values (@kelly)";
SqlConnection con = new SqlConnection(connectionString);
SqlCommand com3 = new SqlCommand(sql,con);
com3.Parameters.Add("@kelly",SqlDbType.Image).Value=imageb;
com3.Connection.Open();
com3.ExecuteNonQuery();
com3.Connection.Close();
6. 在页面输出图片的时候,必须使用的一个标签是
<asp:Image ID="Image1" runat="server" Height="300px" Width="300px" />
然后在后台付给image的url:例如:
this.Image1.ImageUrl = "DisplayOneImage.aspx";
在使用的时候必须注意使用的必须是aspx或者是ashx,不能够使用ascx,具体的原因好像是ascx必须承载在aspx中,它并不能够单独使用
7. 另外的一种情况就是一个页面上需要显示多个图片,在使用Datagrid的时候
使用的原理:利用DataGrid进行绑定数据,然后在后台赋给数据源,
<ItemTemplate>
<asp:Image ID="Image1" runat="server" Height="300px" ImageUrl='<%# "Getimg.ashx?id="+Eval("id") %>'
Width="300px" />
</ItemTemplate>
在ItemTemplate中使用一个Image控件,然后使用IMageUrl标签来对数据源进行赋值给数据,建立一个ashx文件,在每次绑定图片的时候,都调用一次这个文件,将图片读出
8. 扩展话题
关于aspx——ascx——ashx的区别
首先声明一下,开始不知道自定义控件和用户控件的区别,以为自定义控件就是用户控件,在无意之中居然发现用户控件和自定义控件是大不相同:
用户控件指的是UserControl,后缀名称为ascx的文件,是Custom Control自定义控件;而自定义控件指的则是ServerControl服务器控件,,后缀名称为dll文件
服务器控件分为用户控件模型和自定义控件,一般而言,用户控件模型适合创建内部,应用程序特定的控件,而自定义控件模型更适合创建通用的和可再分发的控件
Web 用户控件 | Web 自定义控件 |
易于创建 | 难于创建 |
为使用可视化设计工具的使用者提供有限的支持 | 为使用者提供完全的可视化设计工具支持 |
每个应用程序中需要控件的一个单独副本 | 仅在全局程序集缓存中需要控件的单个副本 |
不能添加到 Visual Studio 中的工具箱 | 可以添加到 Visual Studio 中的工具箱 |
适用于静态布局 | 适用于动态布局 |
.aspx:for ASP.NET Web pages
.asmx:for ASP.NET Web services
.ashx:for custom ASP.NET HTTP handelers
.rem:for remotig resources
.config:for ASP.NET configuration files
And others
相关的页面包括:MYImage.aspx;MyImage1.aspx;DisplayMoreImage.aspx;DisplayOneImage.aspx;DisplayOneImage.aspx;Getimg.ashx;TestDisplay.aspx;TestModel.aspx
后续问题:
1. 当用实体类进行上传图片的时候,如果图片未上传,但是用实体类的参数方法必须提供此参数image类型,并且需要image的长度,从而进行修改实体类的update方法,传入一个实体类的同时,将这个image的长度设置为0,同时实体类中必须进行图片的新的二进制数组形式
2. 当用实体类进行修改的时候,必须判断路径是否存在,如果图片路径存在的话那么获得图片的二进制格式存储,并且在update方法中必须进行传入当前这个二进制的长度,否则会出错
3. public string Add(DataAccess.Model.tb_rck model, int len)
4. new SqlParameter("@photo", SqlDbType.Image,len),
5. public void Update(DataAccess.Model.tb_rck model,int len)
6. model.photo = ds.Tables[0].Rows[0]["photo"] as byte[];
7. 在用实体类的时候,必须要考虑到各个参数是否正确的提供了,从而会不会发生是不是有的参数未提供,导致错误
8. 在进行图片传值的时候,使用image控件,在后台给这个image控件赋值给ImageUrl,这个ImageUrl必须是其他的aspx页面或者是一个ashx文件,在使用这个的时候也就是说这个必须进行两次数据库的读写操作,可否找到一个只读写一次的方法,并且可以直接将图片显示出来,~
个人愚见。。。。。。。。。。。