سلام، خوبین؟
چه جوری می تونم یه عکس رو تو پایگاه داده SQL SEREVR دخیره کنم؟ تو سمت C++BUILDER از چه نوعی استفاده کنم؟
سلام، خوبین؟
چه جوری می تونم یه عکس رو تو پایگاه داده SQL SEREVR دخیره کنم؟ تو سمت C++BUILDER از چه نوعی استفاده کنم؟
سلام
به روشهای مختلف می شود این کار را انجام داد فرضا اگر برای ارتباط با پایگاه داده از ADO استفاده کرده باشید می توانید چنین کدی را بکار برید:
TFileStream * sImage;
TStream * sField;
sImage = new TFileStream("..\\MyPic.bmp", fmOpenRead);
ADOQuery1->Append();
__try
{
sField = ADOQuery1->CreateBlobStream(ADOQuery1->FieldByName("My_Field"), bmWrite);
sField->CopyFrom(sImage, sImage->Size);
}
__finally
{
delete sField;
}
ADOQuery1->Post();
delete sImage;
در روش بالا با CreateBlobStream توسط یک Stream مستقیما به Field تصویر در بانک اطلاعاتی متصل میشوید با تغییر پارامتر دوم می توانید این Stream را برای read, write یا read/write بکار برید.
نکته: قبل از فراخوانی تابع Post حتما باید stream ایجاد شده حذف گردد.
آخرین ویرایش به وسیله sasan_vm : چهارشنبه 15 مهر 1388 در 09:44 صبح
سلام
با تشکر،
با استفاده از روشی که گفتین تونستم عکس رو ذخیره کنم، ولی نمی تونم بازیابیش کنم. چه جوری می شه بازیابی کرد؟
سلام
اگه فایل تصویری bmp هست به روش قبل یک stream به فیلد تصویری ایجاد کنید با پارامتر bmRead و یک
TImage روی فرم بذارید و با این کد تصویر را load کنید:
Image1->Picture->Bitmap->LoadFromStream(Stream);
سلام
خیلی ممنون، مشکلم حل شد.
اما اگر فایل ا ز جنس Jpeg بود باید چکار کنم؟
#include <Jpeg.hpp>
...
TJPEGImage * jpgImg;
...
jpgImg = new TJPEGImage;
jpgImg->LoadFromStream(Stream);
Image1->Picture->Assign(jpgImg);
بازم ممنون
ولی اگه بخوام به کاربر اجازه بدم بیش از یک نوع فایل رو آپلود کنه، زمان بازیابی چطوری تشخیص بدم که فایل از چه نوعیه؟ تا یه استریم از همون نوع ایجاد کنم. البته من یه کد دلفی براش پیدا کردم ولی نمیتونم تبدیل به سی بکنم
procedure TForm1.btnLoadClick(Sender: TObject);
var
s: TStream;
buf: word;
gf: TGraphic;
begin
Query1.SQL.Text := 'SELECT img FROM htest';
Query1.Open;
Query1.First;
s := Query1.CreateBlobStream(Query1.FieldByName('img'), bmRead);
try
if s.read(buf, sizeof(buf)) <> sizeOf(buf) then exit;
s.Position := 0;
if buf = $D8FF then
gf := TJPEGImage.Create
else if buf = $4D42 then
gf := TBitmap.Create
else if buf = $CDD7 then
gf := TMetafile.Create
else if buf = 0 then
gf := TIcon.Create;
try
gf.LoadFromStream(s);
Image1.Picture.Graphic := gf;
finally
gf.Free;
end;
finally
s.Free; // must free stream
end;
end;
راستش من اون خطی رو که قرمز کردم اصلا نمیفهمم. میشه برام توضیح بدین
البته در مورد ادرسهایی که قرمز شده هم توضیح بدینif buf = $D8FF then
gf := TJPEGImage.Create
else if buf = $4D42 then
gf := TBitmap.Create
else if buf = $CDD7 then
gf := TMetafile.Create
فایلهای تصویری (gif, bmp, jpg, ...) یک امضاء دارند که در 2 بایت یا 4 بایت اول فایل ذخیره میشود
که با تست آن می توانید متوجه شوید که آن فایل چه قالب بندی دارد. در مثالی که ارسال کردید از
همین روش استفاده شده است اگر از یک Binary Editor مانند winhex استفاده کنید و با آن این فایلهای گرافیکی را باز کنید متوجه میشوید 2 بایت اول فایلهای گرافیکی ذیل به این صورت است:
bmp: 0x424D (BM)
jpg: 0xFFD8
gif: 0x4749463839 (GIF98))
.
.
در کد قرمز رنگ به اندازه حافظه ای که برای word در دلفی ذخیره می شود (2 یا 4 بایت وابسته به سیستم عامل و کمپایلر) از stream می خواند تابع read , write در stream همیشه تعداد بایت نوشته/خوانده شده را برمی گردانند تا اگر خطایی رخ داده باشد بتوان چک کرد.
در کد معادل در C چون می خواهیم 2 بایت را چک کنیم بهتر است دقیقا مشخص کنیم
2 بایت از stream بخواند تا از خطای اندازه متغیر ها در سیستم عامل و کمپایلر جلوگیری شود.
بعد از این کد متغیر buf حاوی 2 بایت اول stream است و می توانید آن را با مقادیر امضاء فایلهای
گرافیکی مقایسه کنید.
if s.read(buf, sizeof(buf)) <> sizeOf(buf) then exit
short int buf, szie = 2;
if (s->read(&buf, size) != size)
exit(0);
آخرین ویرایش به وسیله sasan_vm : یک شنبه 13 تیر 1389 در 21:19 عصر
اولا شما گفتین که در سی اون اکضا دوبایتیه ولی با کد زیر
bmp: 0x424D (BM)
jpg: 0xFFD8
که البته در مورد gif به نظر میرسه که بیشتر باشه
gif: 0x4749463839 (GIF98))
مشکل اینه که من همین gif رو نمیتونم توی Image نشون بدم
در ضمن برای فایلهای دیگه ای مثل tif, png من میتونم اونا رو توی بانک اطلاعاتی ذخیره کنم ولی زمانی که میخوام object لازم رو برای خوندنشون ایجاد کنم چیز مناسبی رو پیدا نمیکنم.
TGraphic * sGraphic;
if (*buf==0xD8FF)
sGraphic=new TJPEGImage;
else if(*buf==0xCDD7)
sGraphic=new TMetafile;
جایی هست که من بتونم برای فرمتهای مختلف عکس ابجکتهای مناسب پیدا کنم
- در bmp , jpg امضا 2 بایتی هست (این ربطی به زبان نداره) ولی همان طور که نوشتم در gif امضا بیشتر هست (GIF98)
احتمالا فکر نمی کنید که 0x424d یا 0xffd8 بیشتر از 2 بایت باشه
- کد لود کردن فایل gif مانند jpg هست فقط باید object را بشناسید البته این object توسط CodeGear ارائه نشده و نویسنده آن Anders Melander هست:
#include <GIFimg.hpp>
...
TGIFImage * gifImg;
gifImg = new TGIFImage;
..
gifImg->LoadFromStream(Stream);
Image1->Picture->Assign(gifImg);
فایلهای png , tiff در bcb پشتیبانی نمی شوند شما می توانید از object های آماده استفاده کنید یا خودتان کد بنویسید. یکی از بهترین component گرافیکی 2D hicomponents هست.
آخرین ویرایش به وسیله sasan_vm : دوشنبه 14 تیر 1389 در 11:18 صبح
من با استقاده از کلاس زیر تونستم gif رو لود کنم
#include <axctrls.hpp>
مرسی از مطالبتون استفاده کردیم