Most popular

วันพุธที่ 8 มิถุนายน พ.ศ. 2554

ใช้ Delphi ยัดรูปลง DB ด้วยวิธีที่ง่ายที่สุด

ผู้เขียนใช้ฐานข้อมูล Microsoft SQL Server 2000 สร้างตารางชื่อ "IMAGE_TEST" มีโครงสร้างดังนี้

CREATE TABLE [dbo].[IMAGE_TEST] (
[IMG_NAME] [varchar] (100) COLLATE Thai_BIN NOT NULL ,
[IMG_FILENAME] [varchar] (100) COLLATE Thai_BIN NOT NULL ,
[IMG] [image] NOT NULL ,
[UPDATE_DATE] [datetime] NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO


ALTER TABLE [dbo].[IMAGE_TEST] WITH NOCHECK ADD
CONSTRAINT [PK_IMAGE_TEST] PRIMARY KEY  CLUSTERED
(
[IMG_NAME]
)  ON [PRIMARY]
GO


ALTER TABLE [dbo].[IMAGE_TEST] WITH NOCHECK ADD
CONSTRAINT [DF_IMAGE_TEST_UPDATE_DATE] DEFAULT (getdate()) FOR [UPDATE_DATE]
GO


การออกแบบหน้าจอด้วย Delphi ง่ายๆ โดยมี Component หลักในการติดต่อฐานข้อมูลคือ ADO ประกอบด้วย AdoConnection(TAdoConnection) และ AdoTable (TAdoTable )ส่งผ่านข้อมูลด้วย DataSource
เมื่อวาง Component ทั้ง 3 ตัวแล้วให้ทำการเชื่อมต่อฐานข้อมูลได้เลย(ในการเชื่อมต่อฐานข้อมูลผู้เขียนจะขอข้ามไป)

หน้าจอ หรือฟอร์มโดยรวมมีลักษณะแบบในรูป
Control ที่อยู่บนฟอร์มทั้งหมดมี 3 ตัว คือ Image(TImage) , DBImage(TDBImage) และ DBNavigator(TDBNavigator)
Component และ Control ทุกตัวผู้เขียนไม่ได้ตั้งชื่อปล่อยให้เป็นค่า Default
คุณสมบัติที่สำคัญที่ต้องกำหนดมีดังนี้
DBNavigator1

Image1
DBImage1
เมื่อทดสอบการทำงานของโปรแกรม Control ที่อยู่บนฟอร์มจะแสดงแค่ Image1 และ DBNavigator1 เท่านั้น ส่วน DBImage1 ให้ทำการตั้งค่า Visible เป็น false ด้วย
คำสั่งการทำงานมีอยู่ 2 Event ด้วยกันคือ
  1. เมื่อสถานะของ DataSource1 เปลี่ยนไปเป็น Insert
  2. เมื่อมีการกดปุ่มของ DBNavigator1

procedure TForm1.DataSource1StateChange(Sender: TObject);
Var
    OpenDlg : TOpenDialog;
    imgName : String;
    fStream : TFileStream;
begin
  with DataSource1 do
   Begin
    //ตรวจสอบสถานะว่าเป็น Insert หรือไม่
    if State in [dsInsert] then
     Begin
        try
           //สร้าง Open Dialog เพื่อเลือกรูปเข้ามา
           OpenDlg:=TOpenDialog.Create(Self);
           OpenDlg.Filter:='Bitmap|*.bmp';

           if OpenDlg.Execute then
           Begin
              if OpenDlg.FileName<>'' then
              Begin
                 //แสดง InputBox เพื่อให้ตั้งชื่อของภาพนี้
                 imgName:=InputBox('เพิ่มรูป','กรุณาตั้งชื่อรูปภาพ','');

                 //อ่านไฟล์ที่เลือกเข้ามาเป็น FileStream.
                 fStream:=TFileStream.Create(OpenDlg.FileName,fmOpenRead);

                 //เพิ่มข้อมูลลงใน DataSet AdoTable1 ผ่าน DataSource
                 DataSet.FieldByName('IMG_NAME').AsString:=imgName;
                 DataSet.FieldByName('IMG_FILENAME').AsString:=OpenDlg.FileName;
                 DataSet.FieldByName('UPDATE_DATE').AsDateTime:=Now;

                 //Field ที่ใช้เก็บรูปภาพให้โหลดจาก FileStream เข้าไป
                 TBlobField(ADOTable1.FieldByName('IMG')).LoadFromStream(fStream);

                 //บันทึก
                 DataSet.Post;

                 //เมื่อบันทึกเสร็จก็ให้เอาภาพที่ DBImage1 ดึงมาจากฐานข้อมูลไปแสดงใน Image1
                 Self.Image1.Picture:= Self.DBImage1.Picture;
               end;
           end;
        finally
              //ทำลาย Object ที่สร้างขึ้นเมื่อหมดประโยชน์
              FreeAndNil(OpenDlg);
        end;
     end;
   end;
end;

procedure TForm1.DBNavigator1Click(Sender: TObject; Button: TNavigateBtn);
begin
    //ถ้ามีการใช้ DBNavigator เลื่อน Record ให้แสดงภาพโดยการโอนภาพจาก DBImage1 มาที่ Image1
    if Button in [nbFirst, nbPrior, nbNext, nbLast] then
       Self.Image1.Picture:= Self.DBImage1.Picture;
end;

เมื่อใช้งาน ทดสอบเพิ่มภาพ หรือลบภาพ และเลื่อน Record ทำได้ปกติ โดยไม่ต้องเขียน Code ใดๆ เพิ่ม
หมายเหตุ
สาเหตุที่ต้องใช้ทั้ง TDBImage และ TImage ก็เพราะ TImage มีสามารถตั้งค่า Proportional จัดการ รักษาสัดส่วนของภาพได้ ใช้วิธีนี้ก็ไม่จำเป็นต้องไปหา Control อื่นๆมาใช้ หรือไม่ต้องเขียน Component ให้ยุ่งยาก

3 ความคิดเห็น:

  1. ไม่ระบุชื่อ17 กันยายน 2557 เวลา 18:28

    ไม่มีง่ายกว่านี้เหรอ

    ตอบลบ
  2. ไม่ระบุชื่อ25 กรกฎาคม 2562 เวลา 16:06

    ยัดใส่ Stream นี่แหละง่ายสุดแล้ว

    ตอบลบ