PDA

View Full Version : ذخیره فایل Jpg در دیتابیس ؟



mojtaba_z
یک شنبه 30 شهریور 1382, 11:41 صبح
سلام
چطوری میشه یه تصویر Jpg را در یه دیتابیس از نوع Access یا Sql Server ذخیره کرد.
(من از AdoQuery استفاده میکنم) لطفا یه مثال بزنید.
ممنون.

SReza1
یک شنبه 30 شهریور 1382, 20:43 عصر
این کار رو نمیشه کرد!! فقط میتونی از memorystream استفاده کنی و فایل jpg را در ان ذخیرخه کنی و اونو در db نگهداری کنی

Kambiz
یک شنبه 30 شهریور 1382, 21:03 عصر
به فرض که یک ADOQuery با یک فیلد از نوع Blob یا Memo به نام BlobField داشته باشیم و بخواهیم تصویر موجود در یک TImage رو در این فیلد ذخیره کنیم (فرض بر این هست که Query در حالت Insert یا Edit قرار داره):


procedure TForm1.btnSaveImageClick(Sender: TObject);
var
Stream: TStream;
begin
Stream := ADOQuery1.CreateBlobStream(ADOQuery1BlobField, bmWrite);
try
Image1.Picture.Graphic.SaveToStream(Stream);
finally
Stream.Free;
end;
end;
و برای خواندن از فیلد و قراردادن تصویر در TImage:


procedure TForm1.btnLoadImageClick(Sender: TObject);
var
Stream: TStream;
begin
Stream := ADOQuery1.CreateBlobStream(ADOQuery1BlobField, bmRead);
try
Image1.Picture.Graphic.LoadFromStream(Stream);
finally
Stream.Free;
end;
end;

در هر دو حالت فرض بر این هست که ویژگی Graphic مقدار دهی اولیه شده و nil نیست.

mojtaba_z
یک شنبه 30 شهریور 1382, 23:22 عصر
سلام به همگی
من وقتی از TStream استفاده میکنم فایل های JPG به BMP تبدیل میشن و بعد در دیتابیس
ذخیره میشن.
مشکل من اینه که تعداد زیادی تصویر JPG دارم و اگه بصورت BMP در دیتابیس ذخیره بشن
حجم دیتابیس خیلی خیلی زیاد زیاد بالا میره . برای این میخام با همان حجم کم بصورت JPG
ذخیره کنم .
بازم ممنوم .

shaniaki
یک شنبه 30 شهریور 1382, 23:39 عصر
با عرض ادب:

در آنصورت باید خود فایل را به صورت Stream در یک Blob ذخیره کنی( بدون بارگذاری آن در یک Image و استفاده از توابع های کلاس های Picture و Graphics)

یه عشق برنامه نویسی خفن

parniant
شنبه 09 آذر 1387, 11:29 صبح
با سلام
ما تو برنامه نویسی از دلفی با بانک sql استفاده می کنیم با توجه به مطالب بالا ما نتونستیم در اس کیو ال نوع blob را پیدا کنیم؟از نوع image استفاده کردیم امادر خط زیر از ADOQuery1BlobField اشکال می گیره
Stream := ADOQuery1.CreateBlobStream(ADOQuery1BlobField, bmWrite);
با اینکه یک جدول با نام blob ساختیم و یه فیلد با نام blobfield از نوع image داریم ما می خواهیم عمل ذخیره و بازیابی عکس رو تو دلفی با بانک اس کیو ال انجام بدیم اگه می شه کمک کنید
ضمنا برای استفاده از قطعه کدهای بالا (که شامل stream , blob) هستند باید نام تابع خاصی رو توی var بنویسیم یا نه؟
می شه در مورد blob ,stream هم توضیح بدین ممنون می شم ؟

shervin farzin
شنبه 09 آذر 1387, 19:22 عصر
سلام
نوع Image در sql همون مقدار BLOB رو ذخيره ميكنه .
در مورد ذخيره و بازيابي عكس در SQL قبلا تو همين سايت بحث شده . به
لينك زير مراجعه كنيد:
http://barnamenevis.org/forum/showthread.php?t=124596
اما در مورد سوال شما بايد دو نكته رو خدمت شما بگم .
اول اين كه كدي كه براي ذخيره كردن Stream نوشتين اشتباه و بايد به صورت زير
اصلاحش كنيد :

stream:=ADOQuery1.CreateBlobStream(ADOQuery1.Field ByName('BlobField'),bmRead);
در ضمن در قسمت Var فقط كافيه Stream رو از نوع Tstream تعريف كنيد .
نكته دوم اينه كه بين ذخيره كردن عكس BMP با عكس JPG فرق هست . فرقش هم
در اينه كه زمان بازيابي اونها اگر پسوند عكس BMP باشه با روشي كه دوستم در پست
شماره 3 ارائه كرده قابل اجراء است ولي اگه پسوند عكس JPG باشه بايد از روش ديگه اي
كه در لينك بالا ملاحظه خواهيد كرد استفاده كنين .
موفق باشيد .

parniant
یک شنبه 10 آذر 1387, 09:17 صبح
با تشکر از شما فرزین عزیز می شه کدی به همین صورت برای بازیابی عکس هم بذارین راستشو بخواین خسته شدم بس که جستجو کردم

m-khorsandi
یک شنبه 10 آذر 1387, 09:51 صبح
ذخیره کل یک فایل در یک فیلد بانک اطلاعاتی (http://www.barnamenevis.org/forum/showthread.php?t=6958)
ذخیره عکس در sql server2000 (http://barnamenevis.org/forum/showthread.php?t=47361)

parniant
یک شنبه 10 آذر 1387, 09:52 صبح
با سلام همانطور که در پست های بالا گفته شده بود که adoquery باید در حالت edit یا insertقرار داشته باشه می خواستم ببینم چطور می تونم adoquery رو در این حالت قرار بدم ؟ و اینکه در هنگام ذخیره و بازیابی edit یا insert باشه فرق می کنه یا نه ؟ (چون با اجرای اون قطعه برنامه بالا پیغام می ده که adoqueryنیست در حالت editیا insert )
با تشکر

shervin farzin
یک شنبه 10 آذر 1387, 10:21 صبح
سلام
فرض كنيد كه جدولي داريم با نام picsample كه توي اين جدول يك فيلد از نوع Image با نام
pic ساختم و عكسم رو هم داخلش ذخيره كردم . براي بازيابي اون عكس از كد زير استفاده
ميكنم :

var
pic:TJPEGImage;
stream:Tstream;
begin
With ADOQuery1 do
begin
sql.text:='select * from picsample';
Open;
end;
stream:=ADOQuery1.CreateBlobStream(ADOQuery1.Field ByName('pic'),bmRead);
if stream.Size<>0 then
begin
if copy(ADOQuery1.FieldByName('pic').AsString,1,1)='B ' then
image1.Picture.Bitmap.LoadFromStream(x)
else
begin
pic:=TJPEGImage.Create;
pic.LoadFromStream(x);
image1.Picture.Assign(pic);
pic.Free;
end;
end
else image1.Picture.Graphic:=nil;
stream.Free;

به يه نكته هم توجه كنيد كه در خط شماره 13 كه با IF كاراكتر اول Stream ذخيره شده در فيلد
pic رو با كاراكتر B مقايسه كردم علت اين بوده كه متوجه شدم اگه فايل عكس با پسوند BMP
باشه اون كاركتر اول مقدارش B ميشه ( در واقع سه كاركتر اول BMP ميشه ) . براي همين تو
اون خط تست ميكنم كه اگه عكس BMP بود از روش Load مخصوص خودش استفاده كنم .
100 البته كه اين يه روش من درآوردي و شايد روش بهتر و بهينه تري هم بتونين براش پيدا كنين .
يه نكته ديگه هم اين كه فراموش نكنيد كه كلاس JPEG رو در ابتداي Unit در بخش Uses اضافه
كنيد . در ضمن با اجراء اون Select كه اول همين كد نوشتم ADOQuery در حالت مورد نياز
قرار ميگيره و كار ديگه اي لازم نداره .
اگه با كد بالا مشكلي نداشتين و بعدا خواستين در مورد حالتي كه كاربر برنامتون براي فيلد
عكس هيچ مقداري در نظر نگيره اطلاعات داشته باشيد به لينك زير يه نگاهي بندازين
http://barnamenevis.org/forum/showthread.php?t=124721
تو اين لينك كد وارد كردن عكس به DataBase هم هست .
موفق باشيد .

parniant
یک شنبه 10 آذر 1387, 17:54 عصر
با سلام به شما کامبیز عزیز و تمام دوستان
من هم همونطوری که شما گفتید عمل کردم اما می خوام ببینم برای بازیابی یک عکس ذخیره شده که برای هر کد یک عکس وارد می کنم (برای صدور کارت افراد ) در کدوم قسمت باید بگم با توجه به شماره کد افراد عکس اون فرد رو نشون بده (می تونید در یک مثال کامل برام بذارید که جدول شامل چهار فیلد کد و نام و نام خانوادگی و عکس هر فرد باشه و بتونم عمل ثبت افراد با عکسشون و و بازیابی عکس هر فرد با توجه به کد او و ویرایش عکس هر فرد با توجه به کد او رو انجام بده ) از دلفی با بانک sql استفاده می کنم ممنون می شم کمک کنید خیلی دنبال گشتم اما چیز درست حسابی پیدا نکردم اگه شما می دونید در تاپیک خاصی هست اگه می شه آدرس اونو برام بذارید ممنون می شم البته اگه به مطلب می خوره

shervin farzin
یک شنبه 10 آذر 1387, 22:20 عصر
سلام
يه برنامه با مشخصاتي كه گفته بوديد رو نوشتم و براتون گذاشتمش ، چند نكته هم در مورد
برنامه بايد اضافه كنم .
1- اين برنامه رو با Delphi 2007 نوشتم .
2- قبل از استفاده كردن ازش حتما محتواي Connection String در كامپوننت AdoQuery رو
مطابق با نام Database خودتون تنظيم كنيد .
3- Personel نام جدول مورد استفاده تو اين برنامست كه چهار فيلد داره
Id كه يه مقدار AutoNumber در جدول تعريف شده .
F_name كه نام پرسنل رو داره
L_name كه نام خانوادگي پرسنل رو داره
Pic كه عكس پرسنل رو نگه ميداره .
4- به رويداد OnCellClick از DBGrid و توابع اعلان شده در بخش Public فرم توجه كنيد .
5- داخل برنامه ، با راست كليك كردن روي Grid عمليات ورود ، ويرايش و حذف رو ميتونين اجراء
كنين ، همچنين با كليك روي سطر مورد نظرتون از Grid عكس ذخيره شده در اون سطر نمايش
داده ميشه .

تا حد امكان سعي كردم فرايندهاي مختلف برنامه رو در قالب توابع از هم جدا كنم تا براي استفاده
مجدد از اونها مشكلي نداشته باشيد . اميدوارم اين برنامه كمكتون كنه .
موفق باشيد .

parniant
دوشنبه 11 آذر 1387, 12:44 عصر
با سلام به شما شروین عزیز از برنامتون هم ممنونم
فقط یک مشکلی که هست این هست که من باید با توجه به نام و نام خانوادگی طرف (البته می شه فقط تنها با idاو هم انجام بدم )عمل بازیابی عکسش رو انجام بدم آیا می تونید در این زمینه بهم کمک کنید یعنی با وارد کردن نام و نام خانوادگی طرف و زدن مثلا یک دکمه عکسش رو نشون بده ( برای صدور کارت )
با تشکر

shervin farzin
دوشنبه 11 آذر 1387, 13:02 عصر
سلام
فرض كنين نام و نام خانوادگي فرد مورد نظر رو داخل Edit1 و Edit2 وارد كردين و عكسشو
ميخواين داخل Image1 ببينيد .
يه دكمه روي فرمتون بذارين و اين كد رو براش بنويسيد :

var
pic:TJPEGImage;
stream:TStream;
begin
with ADOQuery1 do
begin
sql.Text:='select * from personel where f_name = :p1 and l_name = :p2';
Parameters.ParamByName('p1').Value:=edit1.Text;
Parameters.ParamByName('p2').Value:=edit2.Text;
Open;
end;
pic:=TJPEGImage.Create;
stream:=ADOQuery1.CreateBlobStream(ADOQuery1.Field ByName('pic'),bmRead);
if stream.Size<>0 then
begin
pic.LoadFromStream(stream);
image1.Picture.Assign(pic);
end
else
image1.Picture.Graphic:=nil;
stream.Free;
pic.Free;


البته اين رو هم اضافه كنم كه جستجو بر اساس فقط نام و نام خانوادگي ممكن بيشتر از يك
نفر رو برگردونه ( مشابهت نام ) ، اين كد كه من نوشتم فقط عكس اولين نفر رو برميگردونه .
اگه بخواين تمام موارد رو پوشش بده فقط كافيه عمل Select رو انجام بدين ( مثل همين Select
كه من اول اين كد بالا نوشتم ) اون وقت نتيجه اين Select رو كاربر روي Grig ميبينه و با انتخاب
هر كدوم عكسش نمايش داده ميشه ( مثل كاري كه توي برنامه Save Picture ديديد )
موفق باشيد .

parniant
دوشنبه 11 آذر 1387, 14:27 عصر
با سلام
در قسمت load

procedure TForm1.Load_pic;
var
pic:TJPEGImage;
stream:tstream;
begin
pic:=TJPEGImage.Create;
Stream:=ADOQuery1.CreateBlobStream(ADOQuery1.Field ByName('pic'),bmRead);
if stream.Size<>0 then
begin
pic.LoadFromStream(stream);
image1.Picture.Assign(pic);
end
else
image1.Picture.Graphic:=nil;
pic.Free;
stream.Free;
end;
چون من از دلفی 6 استفاده می کنم نوع TJPEGImage رو برای pic نمی شناسه باید از چه نوعی استفاده کنم
باتشکر

parniant
دوشنبه 11 آذر 1387, 16:54 عصر
با سلام
من برای بازیابی عکس از دستور زیر


var
pic:TJPEGImage;
stream:TStream;
begin
frmsabt.Image2.Stretch:=true;
with ADOQuery4 do
begin
sql.Text:='select * from tteacher where ido= :p1';
Parameters.ParamByName('p1').Value:=ComboBox3.Text ;
Open;
end;
// begin
// sql.Text:='select * from personel where f_name = :p1 and l_name = :p2';
// Parameters.ParamByName('p1').Value:=edit1.Text;
// Parameters.ParamByName('p2').Value:=edit2.Text;
// Open;
// end;
pic:=TJPEGImage.Create;
stream:=ADOQuery4.CreateBlobStream(ADOQuery4.Field ByName('pic'),bmRead);
if stream.Size<>0 then
begin
if copy(ADOQuery4.FieldByName('pic').AsString,1,1)='B ' then
image2.Picture.Bitmap.LoadFromStream(stream)
else
begin
pic.LoadFromStream(stream);
image2.Picture.Assign(pic);
end;
end
else
image2.Picture.Graphic:=nil;
stream.Free;
pic.Free;
end;

استفاده می کنم اگه بخوام در هنگام ذخیره عکس ، عکس های با پسوند gif رو هم ذخیره کنم در هنگام بازیابی از چه دستوراتی در وسط این دستور استفاده کنم

shervin farzin
دوشنبه 11 آذر 1387, 19:05 عصر
سلام
براي استفاده از تصاوير GIF بايد ابتدا در بخش Uses فرمتون ، GIFImg رو اضافه كنيد .
بعدش توي همين كد Load كه نوشته بوديد هر جا نوشتين TJpegImage ، اونو با
TGIFImage عوض كنيد .
در مورد وضعيت نوع TJPEGImage بايد خدمتتون بگم اين نوع داده از انواع ارائه شده در كلاس
JPEG هست و تا زماني كه شما اين كلاس رو Uses نكنيد در اختيارتون قرار نميگيره ، اما اگه اين
كلاس رو در بخش Uses نوشتيد و همچنان چنين نوع داده اي رو نمي بينيد متاسفانه در مورد
نوع داده مشابه در دلفي 6 من اطلاعاتي ندارم تا به شما كمك كنم .
موفق باشيد .

mrm0101
دوشنبه 11 آذر 1387, 19:35 عصر
سلام .

از کامپت Developer Express استفاده کنید . نیاز به کد نویسی ندارد
cxDBImage از فرمت jepg پشتیابنی می کند .

parniant
دوشنبه 11 آذر 1387, 21:05 عصر
با سلام
شروین عزیز می شه بگید در اون قطعه برنامه ای که نوشته بودید برای ویرایش که از این دستور استفاده کرده اید

begin
if (edit1.Text<>'') or (edit2.Text<>'') then
begin
Edit_db(ADOQuery1.FieldByName('id').Value);
button1.Click;
end
else
showmessage('Error'+#13+'Enter Name and Family');
end;
در خط

Edit_db(ADOQuery1.FieldByName('id').Value);

از کجا تشخیص بده که id من برای ویرایش الان چند است در حقیقت باید کدی رو برای ویرایش کردن بگیره اون کد رو کجا گفتین که از کاربر بگیره (اگر هم در تابع procedure TForm1.Edit_db(id: integer); گفتین می شه بگین کدوم خطش است ) با تشکر

shervin farzin
دوشنبه 11 آذر 1387, 23:34 عصر
سلام
همونطور كه در برنامه ملاحظه كرديد عمل ويرايش بعد از انتخاب يك نفر در DBGrid اتفاق ميفته
در OnCreate فرم برنامه تابعي فراخواني شده كه كارش اجراء يك دستور Select هست كه در
نتيجه خروجي اين Select كه محتويات جدول شماست داخل Dataset قرار ميگيره .
با انتخاب يك سطر از Grid در واقع Dataset Record Pointer ( اشاره گري كه در هر لحظه به يكي
از سطر هاي Dataset اشاره ميكنه ) رو به اون خط منتقل كرديد .
به اين ترتيب ميتونم به محتويات تمام فيلدهاي اون سطر انتخاب شده دسترسي داشته باشم
به عنوان مثال اگه نام فرد رو ميخواستم بايد به اين ترتيب عمل كنم :

ADOQuery1.FieldByName('F_name').Value
كه مقدار F_name رو به صورت String برام بر ميگردونه .
در مورد خاص اين برنامه من براي اجراء فرايند Edit و در واقع اجراء تابع Edit_db نياز به ID فرد
انتخاب شده دارم به همين منظور براي به دست آوردن ID از كد زير استفاده ميكنم :

ADOQuery1.FieldByName('id').Value
اين خط يك مقدار Integer به من برميگردونه كه همون Id فرد انتخاب شده ميشه ، من ميتونستم
اول خروجي اين خط رو در يك متغيير Integer ذخيره كنم و بعد اون متغيير رو به عنوان ورودي به
تابع Edit_db بدم يا مثل كاري كه در كد برنامه ملاحظه كردين مستقيما همين خط رو در ورودي
تابع Edit_db بنويسم .
اميدوارم توضيحم واضح باشه . موفق باشيد

parniant
سه شنبه 12 آذر 1387, 07:57 صبح
با سلام به شما شروین عزیز و سایر دوستان
می خواستم ببینم چه زمانی لازمه از Bmwrite استفاده کنیم ( به جای bmread در دستوراتمون ) باتشکر