首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Delphi 資料庫影像存取完整方案:BMP/JPEG 格式支援、TImage 顯示、Blob 串流操作

     編輯:更多程式設計知識

資料庫儲存影像是常見需求,但 TDBImage 僅支援 BMP,無法正確顯示 JPEG。本文提供完整方案:使用 TImage 搭配 TJPEGImage 實現 BMP/JPEG 雙格式顯示,透過 TMemoryStream 讀寫 Blob 欄位,並以輔助欄位記錄影像格式,支援 SQL Server / Access 等主流資料庫。

資料庫結構設計


-- SQL Server 範例
CREATE TABLE Picture1 (
    ID       INT IDENTITY(1,1) PRIMARY KEY,
    IsBMP    TINYINT      NOT NULL DEFAULT 2, -- 0=JPEG, 1=BMP, 2=無圖片
    MyImage  IMAGE        NULL                -- Blob 欄位
);
TINYINT 而非 BIT,因 Access 不支援 BIT 型別,通用性更佳。

表單元件配置

元件名稱關鍵屬性用途
TImageImage1Stretch=True顯示 BMP/JPEG 影像
TButtonbtnSelectCaption='選擇影像'開啟檔案對話框
TButtonbtnSaveCaption='儲存至資料庫'寫入 Blob
TOpenPictureDialogOpenPicDlgFilter='影像檔|*.bmp;*.jpg;*.jpeg'選擇影像檔
TADOConnectionAdoConnConnectionString=...; Connected=True資料庫連線
TADOTableAdoTableTableName='Picture1'; Active=True資料集
TDataSourceDataSrcDataSet=AdoTable資料綁定
TDBGridDBGrid1DataSource=DataSrc顯示記錄列表

核心單元引用


uses
  ..., JPEG; { 必須引用 JPEG 單元,才能使用 TJPEGImage }

完整程式碼實作

選擇影像並顯示


procedure TForm1.btnSelectClick(Sender: TObject);
begin
  if OpenPicDlg.Execute then
    Image1.Picture.LoadFromFile(OpenPicDlg.FileName);
end;

儲存影像至資料庫 (核心邏輯)


procedure TForm1.btnSaveClick(Sender: TObject);
var
  MS: TMemoryStream;
  Ext: string;
begin
  if Image1.Picture.Graphic = nil then begin
    ShowMessage('請先選擇影像');
    Exit;
  end;

  Ext := UpperCase(ExtractFileExt(OpenPicDlg.FileName)); // .BMP / .JPG / .JPEG

  MS := TMemoryStream.Create;
  try
    // 1. 將 Picture 內容存入記憶體串流
    Image1.Picture.Graphic.SaveToStream(MS);
    MS.Position := 0;

    // 2. 寫入 Blob 欄位
    AdoTable.Edit;
    TBlobField(AdoTable.FieldByName('MyImage')).LoadFromStream(MS);
    // 替代寫法:直接從檔案 LoadFromFile(OpenPicDlg.FileName)

    // 3. 記錄格式標記
    if Ext = '.BMP' then
      AdoTable.FieldByName('IsBMP').Value := 1
    else if (Ext = '.JPG') or (Ext = '.JPEG') then
      AdoTable.FieldByName('IsBMP').Value := 0
    else
      AdoTable.FieldByName('IsBMP').Value := 2; // 未知格式

    AdoTable.Post;
    ShowMessage('儲存成功');
  finally
    MS.Free; // 釋放串流
  end;
end;

從資料庫讀取並顯示 (自動識別格式)


procedure TForm1.AdoTableAfterScroll(DataSet: TDataSet);
var
  MS: TMemoryStream;
  IsBMP: Integer;
begin
  Image1.Picture := nil; // 清空舊圖
  IsBMP := AdoTable.FieldByName('IsBMP').AsInteger;

  if IsBMP = 2 then Exit; // 無圖片

  MS := TMemoryStream.Create;
  try
    TBlobField(AdoTable.FieldByName('MyImage')).SaveToStream(MS);
    MS.Position := 0;

    if IsBMP = 1 then
      Image1.Picture.Bitmap.LoadFromStream(MS) // BMP
    else
      Image1.Picture.Graphic.LoadFromStream(MS); // JPEG (透過 TJPEGImage 自動識別)
      // 或明確: TJPEGImage(Image1.Picture.Graphic).LoadFromStream(MS);
  finally
    MS.Free;
  end;
end;

關鍵技術細節

項目說明
TImage vs TDBImageTDBImage 綁定資料集但**僅支援 BMP**;TImage 需手動讀寫,但支援所有 TPicture 註冊的格式 (BMP/JPEG/GIF/PNG/ICO/WMF/EMF)。
格式識別策略資料庫 Blob 本身**不含格式資訊**,必須額外欄位 (IsBMP) 記錄,或檢測檔案標頭 (Magic Bytes: BMP=42 4D, JPEG=FF D8 FF)。
MemoryStream 釋放務必在 try..finally 中 Free,避免記憶體洩漏。切勿使用 TBlobStream 當作區域變數,其行為在某些 Delphi 版本異常。
大圖片效能超過 10MB 影像建議:
• 分塊讀寫 (TBlobStream Seek/Read)
• 資料庫啟用 Filestream (SQL Server 2008+)
• 僅存路徑,檔案放磁碟。
Access 相容性Access 使用 OLE Object 型別儲存影像,實際為包裝過的 Blob,LoadFromStream/SaveToStream 同樣適用。

進階:支援更多格式 (GIF/PNG/WEBP)

  1. 安裝第三方圖形庫 (如 GraphicEx、PngComponents)。
  2. 在專案 uses 中引入對應單元 (PngImage, GIFImg 等)。
  3. TPicture 會自動註冊新格式,Image1.Picture.LoadFromFile/Stream 即可支援,無需修改核心邏輯。
  4. 格式欄位擴充為字串 (ImgFormat: string[10]) 存儲 'BMP'/'JPG'/'PNG'/'GIF',讀取時依格式建立對應 TGraphic 子類實例。

結語

「TImage + TMemoryStream + 格式標記欄位」是 Delphi 資料庫影像存取的黃金組合:支援多格式、不依賴 TDBImage、相容主流資料庫、代碼簡潔可維護。掌握 SaveToStream/LoadFromStream、TBlobField 操作、JPEG 單元引用三大關鍵,即可構建穩健的影像管理模組。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved