PDA

View Full Version : نحوه ذخیره عکس در دیتابیس از طریق برنامه بصورت varbinary?



baran110
دوشنبه 01 بهمن 1386, 11:31 صبح
ببخشید.من هر چی سرچ کردم در این تاپیک ها در این مورد به نتیجه نرسیدم که چطور بتونم با C#.net و ASP.Net عکس ها را تبدیل به varbinary کرده و در دیتابیس ذخیره کنم.اگر کسی می تونه کمکم کنه بکنه.اگر هم کسی در سرچ به نتیجه ای رسیده خواهشمندم لینکش رو برام بگذاره.

dr_csharp
دوشنبه 01 بهمن 1386, 14:27 عصر
سلام
اول فایلت ( تصویر یا هر چیز دیگه .. ) رو بصورت FileStream باز میکنی :

FileStream fs = new FileStream("d:\\1.jpg",FileMode.Open);
بعد تو یه آرایه از نوع بایتی میریزیش :

FileInfo fi = new FileInfo("d:\\1.jpg");
byte[] jpg = new byte[(int)fi.Length];
fs.Read(jpg, 0, (int)fi.Length);

حالا jpg رو میریزی تو بانک :لبخندساده:

Alireza_Salehi
دوشنبه 01 بهمن 1386, 16:45 عصر
Byte[] Buffer = System.IO.File.ReadAllBytes(Server.MapPath("relativeFilePath"));
System.Data.SqlClient.SqlCommand cmd=
new System.Data.SqlClient.SqlCommand("INSERT INTO Table1 (img) VALUES (@image)",
new System.Data.SqlClient.SqlConnection("connectionString"));
cmd.Parameters.Add("@image", System.Data.SqlDbType.VarBinary).Value = Buffer;
cmd.ExecuteNonQuery();

mahdi_farhani
دوشنبه 01 بهمن 1386, 22:52 عصر
دوستان راهنمایی های لازم رو کردن ، ولی من راهنمایی که میتونم بکنم اینه که به هیچ عنوان باینری در دیتابیس ذخیره نکنید .
حجم دیتابیست الکی بالا میره ، حالا یه بار تبدیل که باینری به ریز تو دیتابیس ، یه بار از دیتابیس بخون به عکس تبدیل ، میدونی چقدر هزینه برداره برای شما .

mehrdad201
سه شنبه 02 بهمن 1386, 00:53 صبح
اره اما کلا واسه جاهایی که مجوز دسترسی باید داده بشه و امنیت اطلاعات بسیار مهم هست.
میتونه خیلی مفید باشه

میشه گفت تقریبا امنیت با سرعت و هزینه رابطه معکوس دارن .....

baran110
سه شنبه 02 بهمن 1386, 17:33 عصر
با تشکر از دوستان .راستش من خودم عکسها رو روی سرور و نام آنها را در دیتابیس ذخیره می کنم ولی در این مورد آخر که تنها عکس کاربرم و برای هر نفر یک فیلد دارم می خوام varbinary ذخیره کنم. راستش یک کدی خودم نوشتم که عکس رو به صورت ور باینری ذخیره کرد.حالا می شه کمکم کنید بگید چطور استریمی رو که از دیتا بیس آوردم رو به کنترلimage بایند کنم تا بتونه اونو نمایش بده. کدی هم که نوشتم به صورت زیر است.

string constr = ConfigurationManager.ConnectionStrings["student"].ConnectionString;
protectedvoid Page_Load(object sender, EventArgs e)
{
showphoto();
}
privatevoid AddPhoto(string photoFilePath)
{

byte[] photo = GetPhoto(photoFilePath);
{
SqlConnection objConnection = new SqlConnection(constr);
SqlCommand command = new SqlCommand("INSERT INTO photo (Picture) " + "Values(@Photo)", objConnection);
command.Parameters.Add("@Photo", SqlDbType.VarBinary , photo.Length).Value = photo;
objConnection.Open();
command.ExecuteNonQuery();
}
}
protectedvoid Button1_Click(object sender, EventArgs e)
{
AddPhoto(@"D:\photo1.jpg");
}
privatebyte[] GetPhoto(string filePath)
{
FileStream stream = newFileStream(filePath, FileMode.Open, FileAccess.Read);
BinaryReader reader = newBinaryReader(stream);
byte[] photo = reader.ReadBytes((int)stream.Length);
reader.Close();
stream.Close();
return photo;
}

//////////////////////////////////////////////////////////////////////////////////////
privatevoid showphoto()
{
SqlConnection objConnection = new SqlConnection(constr);
DataSet objDataSet = new DataSet();
SqlDataAdapter objDataAdapter = new SqlDataAdapter();
objDataAdapter.SelectCommand = new SqlCommand();
objDataAdapter.SelectCommand.CommandText = "SELECT Picture FROM photo where id=11";
objDataAdapter.SelectCommand.CommandType = CommandType.Text;
objDataAdapter.SelectCommand.Connection = objConnection;
objDataAdapter.Fill(objDataSet, "photo");
DataView objDataView = new DataView(objDataSet.Tables["photo"]);
objConnection.Open();
byte[] arrPicture = ((byte[])(objDataSet.Tables[0].Rows[0][0]));
//MemoryStream ms = new MemoryStream(arrPicture);
StreamReader rs = newStreamReader(arrPicture);
//از اینجا به بعد دیگه نمی دونم چکار کنم.

}


// }

DotNet_King
چهارشنبه 03 بهمن 1386, 00:18 صبح
سلام
اول فایلت ( تصویر یا هر چیز دیگه .. ) رو بصورت FileStream باز میکنی :

FileStream fs = new FileStream("d:\\1.jpg",FileMode.Open);
بعد تو یه آرایه از نوع بایتی میریزیش :

FileInfo fi = new FileInfo("d:\\1.jpg");
byte[] jpg = new byte[(int)fi.Length];
fs.Read(jpg, 0, (int)fi.Length);

حالا jpg رو میریزی تو بانک :لبخندساده:



اگه ممکنه راجع به روش کار ریختن استریم به بایت بیشتر توضیح بدید و این jpg رو به چه صورت میشه از بانک خوند؟ این بایت کردن عکس به هر فایل باینری - مثلا exe- قابل تعمیمه؟

Alireza_Salehi
چهارشنبه 03 بهمن 1386, 13:33 عصر
با تشکر از دوستان .راستش من خودم عکسها رو روی سرور و نام آنها را در دیتابیس ذخیره می کنم ولی در این مورد آخر که تنها عکس کاربرم و برای هر نفر یک فیلد دارم می خوام varbinary ذخیره کنم. راستش یک کدی خودم نوشتم که عکس رو به صورت ور باینری ذخیره کرد.حالا می شه کمکم کنید بگید چطور استریمی رو که از دیتا بیس آوردم رو به کنترلimage بایند کنم تا بتونه اونو نمایش بده. کدی هم که نوشتم به صورت زیر است.

string constr = ConfigurationManager.ConnectionStrings["student"].ConnectionString;
protectedvoid Page_Load(object sender, EventArgs e)
{
showphoto();
}
privatevoid AddPhoto(string photoFilePath)
{

byte[] photo = GetPhoto(photoFilePath);
{
SqlConnection objConnection = new SqlConnection(constr);
SqlCommand command = new SqlCommand("INSERT INTO photo (Picture) " + "Values(@Photo)", objConnection);
command.Parameters.Add("@Photo", SqlDbType.VarBinary , photo.Length).Value = photo;
objConnection.Open();
command.ExecuteNonQuery();
}
}
protectedvoid Button1_Click(object sender, EventArgs e)
{
AddPhoto(@"D:\photo1.jpg");
}
privatebyte[] GetPhoto(string filePath)
{
FileStream stream = newFileStream(filePath, FileMode.Open, FileAccess.Read);
BinaryReader reader = newBinaryReader(stream);
byte[] photo = reader.ReadBytes((int)stream.Length);
reader.Close();
stream.Close();
return photo;
}

//////////////////////////////////////////////////////////////////////////////////////
privatevoid showphoto()
{
SqlConnection objConnection = new SqlConnection(constr);
DataSet objDataSet = new DataSet();
SqlDataAdapter objDataAdapter = new SqlDataAdapter();
objDataAdapter.SelectCommand = new SqlCommand();
objDataAdapter.SelectCommand.CommandText = "SELECT Picture FROM photo where id=11";
objDataAdapter.SelectCommand.CommandType = CommandType.Text;
objDataAdapter.SelectCommand.Connection = objConnection;
objDataAdapter.Fill(objDataSet, "photo");
DataView objDataView = new DataView(objDataSet.Tables["photo"]);
objConnection.Open();
byte[] arrPicture = ((byte[])(objDataSet.Tables[0].Rows[0][0]));
//MemoryStream ms = new MemoryStream(arrPicture);
StreamReader rs = newStreamReader(arrPicture);
//از اینجا به بعد دیگه نمی دونم چکار کنم.

}


// }

کنترل System.Web.UI.WebControls.Image مثل کنترل System.Windows.Forms.PictureBox قابلیت دریافت تصویر از کلاس Bitmap یا Image رو نداره. اگر داشت کافی بود با متد FromStream یکی از این دو کلاس Stream رو تبدیل به عکس کنید و به خاصیت Image کنترل PictureBox نسبت بدید.

System.Web.UI.WebControls.Image تنها از طریق خاصیت ImageUrl تصویر قبول میکنه. این URL میتونه آدرس یک Page یا یک HttpHandler باشه که داخلش به صورت دینامیک با عکس پر میشه.

پارامتر های مورد نیاز برای پیدا کردن و خواندن عکس از دیتابیس رو هم میشه با QueryString به Page یا HttpHandler مورد نظر ارسال کرد.

بنابراین به ترتیب باید مراحل زیر رو انجام بدید:
1. یک GenericHandler به وب سایت خود اضافه کنید (مثلا با نام ImageHandler.ashx).
2. در متد ProcessRequest در فایل ImageHandler.ashx به صورت زیر تصویر را می خوانیم و در خروجی ترسیم میکنیم (این تصویر در کنترل Image نمایش داده خواهد شد):

public void ProcessRequest (HttpContext context) {
using (SqlConnection con = new SqlConnection("connectionString"))
{
using (SqlCommand cmd = new SqlCommand(con, "SELECT Picture FROM photo where id=@ID"))
{
cmd.Parameters.Add("@ID", SqlDbType.Int) = Convert.ToInt32( context.Request.QueryString["ID"]);
con.Open();
Byte[] image =(Byte[]) cmd.ExecuteScalar();
con.Close();
context.Response.Clear();
context.Response.ContentType = "image/jpeg";
context.Response.BinaryWrite(image);
}
}
}


3.حالا کافیه هر جایی که قراره کنترل Image رو پر کنید یک آدرس بسازید و به ImageUrl اون نسبت بدید.مثلا فرض کنید HttpHandler رو در ریشه وب سایت قرار داده اید و متغییر id شماره عکس رو در خودش داشته باشه:



Image1.ImageUrl = "~/ImageHandler.ashx?ID=" + id.ToString();



اگر می خواهید به حای HttpHandler از Page استفاده کنید کافیه کدهای متد ProcessRequest رو در Page_Load کپی کنید.

جزئیات بیشتر رو هم اینجا ببین: Personal Web Site (http://www.asp.net/downloads/starter-kits/personal/)

mehrdad201
چهارشنبه 03 بهمن 1386, 17:59 عصر
دو راه دارید...
یا از handler ها استفاده کنید

یا از یه صفحه aspx

در حالت استفاده از صفحه aspx
توی صفحه اصلیتون باید یه کنترل ایمیج قرار بدید بعد navigationurl رو باید روی یک صفحه aspx ( مثلا با عنوان createimage.aspx) تنظیم کنید و در قسمت انتهاییش هم کوئری استرینگ رو برحسب آی دی رکورد فعلی ایجاد کرده و به انتهای navigation url اضافه کنید.

در صفحه aspx (مثلا createimage.aspx)
باید کانتنت صفحه رو عوض کنید و اون رو jpeg یا gif یا ... قرار بدید. کشینگ رو در صفحه غیر فعال کتید. بعد هم از طریق کوئری استرینگ ای که پاس شده آی دی اون رکوردی رو که میخواید تصویر رو بیرون بکشید دریافت کنید.

بعد رشته باینری رو توی ارایه بایت ریخته و در پایان هم response.binarywrite کنید.

به همین راحتی

===========
در مورد سیو کردن هم کافیه stream تصویر رو توی ارایه بایتی ریخته و اونو در دیتابیس سیو کنید.

یه سرچ در فروم بکنید کلی اطلاعات پیدا میکنید.

c#_web
چهارشنبه 15 اسفند 1386, 11:06 صبح
دو راه دارید...
یا از handler ها استفاده کنید

یا از یه صفحه aspx

در حالت استفاده از صفحه aspx
توی صفحه اصلیتون باید یه کنترل ایمیج قرار بدید بعد navigationurl رو باید روی یک صفحه aspx ( مثلا با عنوان createimage.aspx) تنظیم کنید و در قسمت انتهاییش هم کوئری استرینگ رو برحسب آی دی رکورد فعلی ایجاد کرده و به انتهای navigation url اضافه کنید.

در صفحه aspx (مثلا createimage.aspx)
باید کانتنت صفحه رو عوض کنید و اون رو jpeg یا gif یا ... قرار بدید. کشینگ رو در صفحه غیر فعال کتید. بعد هم از طریق کوئری استرینگ ای که پاس شده آی دی اون رکوردی رو که میخواید تصویر رو بیرون بکشید دریافت کنید.

بعد رشته باینری رو توی ارایه بایت ریخته و در پایان هم response.binarywrite کنید.

به همین راحتی

===========
در مورد سیو کردن هم کافیه stream تصویر رو توی ارایه بایتی ریخته و اونو در دیتابیس سیو کنید.





اگه نخواهیم از handler برویم در صفحه aspx چگونه باید navigationurl را تنظیم کرد؟
اگه ممکنه مطالبی را که بیان کردید با جزئیان بیشتری توضیح دهید.

c#_web
چهارشنبه 15 اسفند 1386, 12:54 عصر
اگر می خواهید به حای HttpHandler از Page استفاده کنید کافیه کدهای متد ProcessRequest رو در Page_Load کپی کنید


من این کدها را در لود صفحه نوشتم اما برای خط


cmd.Parameters.Add("@ID", SqlDbType.Int) = Convert.ToInt32( context.Request.QueryString("ID"));
con.Open();


خطا میدهد که
Error 1 The left-hand side of an assignment must be a variable, property or indexer
]چه کار باید بکنم؟

Alireza_Salehi
پنج شنبه 16 اسفند 1386, 05:54 صبح
QueryString["ID"]

c#_web
پنج شنبه 16 اسفند 1386, 11:30 صبح
من در برنامه ام یک دیتاگرید دارم که اطلاعات را از دیتابیس خوانده و در لود صفحه پر میشود. حالا در هر سطر هم یک دکمه نمایش گذاشتم که آنرا که کلیک کرد ، عکس مربوط به آن سطر را نشان دهد.البته در همین صفحه ای که هستم در کنترل image.
context.Response.BinaryWrite(image); باعث میشود که عکس روی کل همین صفحه باز شود اما من میخواهم فقط در قسمت image برود.

در قسمت itemcommand از دیتاگرید هم کدهای زیر را نوشتم.



int id = int.Parse(dg_show.DataKeys[e.Item.ItemIndex].ToString());
DB.con_open();
DataSet ds_pic = new DataSet();
ds_pic.Clear();
SqlCommand com_pic = new SqlCommand("pic_binarry", DB.con_str);
com_pic.CommandType = CommandType.StoredProcedure;
com_pic.Parameters.Add("@F1", id);
SqlDataAdapter da_pic = new SqlDataAdapter(com_pic);
da_pic.Fill(ds_pic, "tbl");
byte[] binaryImage = (byte[])ds_pic.Tables["tbl"].Rows[0][0];
Response.Clear();
Response.BinaryWrite(binaryImage);
DB.con_close();

که id همان F1 و id سطر جاری است.
و pic_binarry یک storedprocedure در sql است که
select F3 from Pars_Trans_01 where F1=@f1
است و F3 فیلد عکس در دیتابیس است.
حالا برای اینکه عکس در همین صفحه در کنتری image نشان داده شود چه کار باید کرد؟