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

DelphiX 教學 (19):TDirectDrawSurface 圖片載入六大方法完整指南

     編輯:Delphi

TDirectDrawSurface 提供了六種載入圖片的方法,涵蓋檔案、串流、VCL 圖形物件、DIB 等多種來源。理解各方法適用場景與效能差異,能靈活處理遊戲資源載入需求。

六大載入方法總覽

方法來源類型適用場景需額外單元
LoadFromFile圖片檔案最常用,支援 BMP/JPG/GIF 等無
LoadFromStream記憶體串流資源檔解壓、網路下載、加密存儲無
LoadFromGraphicTGraphic 物件整合 VCL 圖形類 (TBitmap/TIcon/TPngImage)無
LoadFromGraphicRectTGraphic + 區域從大圖裁剪載入 (圖集/精靈表)無
LoadFromDIBTDIB 物件進階像素操作、自訂調色盤、非標準格式DIB
LoadFromDIBRectTDIB + 區域 + 縮放DIB 裁剪並縮放到指定尺寸DIB

完整測試範例

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DXDraws, StdCtrls, DIB;  // 最後兩個方法需引用 DIB 單元

type
  TForm1 = class(TForm)
    DXDraw1: TDXDraw;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  ImgPath1 = 'C:\Temp\DelphiX.bmp';

procedure TForm1.Button1Click(Sender: TObject);
var
  MySurface: TDirectDrawSurface;
begin
  MySurface := TDirectDrawSurface.Create(DXDraw1.DDraw);
  try
    MySurface.LoadFromFile(ImgPath1);  // 1. 直接載入檔案
    DXDraw1.Surface.Fill($EEEEEE);  // 淺灰背景區分
    DXDraw1.Surface.Draw(0, 0, MySurface);
    DXDraw1.Flip;
  finally
    FreeAndNil(MySurface);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  MySurface: TDirectDrawSurface;
  stream: TMemoryStream;
begin
  MySurface := TDirectDrawSurface.Create(DXDraw1.DDraw);
  stream := TMemoryStream.Create;
  try
    stream.LoadFromFile(ImgPath1);
    MySurface.LoadFromStream(stream);  // 2. 從記憶體串流載入
    DXDraw1.Surface.Fill($CCCCCC);
    DXDraw1.Surface.Draw(0, 0, MySurface);
    DXDraw1.Flip;
  finally
    FreeAndNil(stream);
    FreeAndNil(MySurface);
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  MySurface: TDirectDrawSurface;
  bit: TGraphic;
begin
  MySurface := TDirectDrawSurface.Create(DXDraw1.DDraw);
  bit := TBitmap.Create;
  try
    bit.LoadFromFile(ImgPath1);
    MySurface.LoadFromGraphic(bit);  // 3. 從 VCL 圖形物件載入
    DXDraw1.Surface.Fill($999999);
    DXDraw1.Surface.Draw(0, 0, MySurface);
    DXDraw1.Flip;
  finally
    FreeAndNil(bit);
    FreeAndNil(MySurface);
  end;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  MySurface: TDirectDrawSurface;
  bit: TBitmap;
begin
  MySurface := TDirectDrawSurface.Create(DXDraw1.DDraw);
  bit := TBitmap.Create;
  try
    bit.LoadFromFile(ImgPath1);
    { 4. 從圖形物件指定區域載入 (來源矩形, 目標尺寸)
       這裡取右下 1/4 區域,繪製到全尺寸表面 }
    MySurface.LoadFromGraphicRect(bit,
      bit.Width div 2, bit.Height div 2,  // 來源左上角
      Rect(0, 0, bit.Width, bit.Height)); // 目標矩形 (這裡似有參數誤解,實際為來源矩形)
    DXDraw1.Surface.Fill($666666);
    DXDraw1.Surface.Draw(0, 0, MySurface);
    DXDraw1.Flip;
  finally
    FreeAndNil(bit);
    FreeAndNil(MySurface);
  end;
end;

procedure TForm1.Button5Click(Sender: TObject);
var
  MySurface: TDirectDrawSurface;
  dib: TDIB;
begin
  MySurface := TDirectDrawSurface.Create(DXDraw1.DDraw);
  dib := TDIB.Create;
  try
    dib.LoadFromFile(ImgPath1);
    MySurface.LoadFromDIB(dib);  // 5. 從 TDIB 載入
    DXDraw1.Surface.Fill($333333);
    DXDraw1.Surface.Draw(0, 0, MySurface);
    DXDraw1.Flip;
  finally
    FreeAndNil(dib);
    FreeAndNil(MySurface);
  end;
end;

procedure TForm1.Button6Click(Sender: TObject);
var
  MySurface: TDirectDrawSurface;
  dib: TDIB;
begin
  MySurface := TDirectDrawSurface.Create(DXDraw1.DDraw);
  dib := TDIB.Create;
  try
    dib.LoadFromFile(ImgPath1);
    { 6. 從 TDIB 載入並縮放至表面尺寸 }
    MySurface.LoadFromDIBRect(dib,
      DXDraw1.Width, DXDraw1.Height,  // 目標寬高
      Rect(0, 0, dib.Width, dib.Height)); // 來源矩形
    DXDraw1.Surface.Fill(0);
    DXDraw1.Surface.Draw(0, 0, MySurface);
    DXDraw1.Flip;
  finally
    FreeAndNil(dib);
    FreeAndNil(MySurface);
  end;
end;

end.

執行效果展示

六種載入方法效果對比,背景顏色區分不同方法

實務選擇指南

  1. 標準資源:優先使用 LoadFromFile,簡單直接。
  2. 記憶體資源:資源檔、加密包、網路下載用 LoadFromStream。
  3. VCL 整合:需用 TPngImage、TJPEGImage 等 VCL 類時用 LoadFromGraphic。
  4. 圖集/精靈表:LoadFromGraphicRect 可從大圖裁剪單幀,但注意參數定義 (來源矩形 vs 目標矩形)。
  5. 進階像素控制:需自訂調色盤、像素格式轉換、非標準位圖時使用 TDIB 相關方法。
  6. 縮放載入:LoadFromDIBRect 可同時裁剪與縮放,適合生成不同解析度的 Mipmap 或縮圖。

常見問題

  • JPG/PNG 支援:LoadFromFile 依賴 VCL 註冊的圖形類,需在專案 uses 中加入 Jpeg, PngImage 等單元。
  • 透明度保留:載入帶 Alpha 通道的 PNG 時,確保目標表面建立時指定含 Alpha 的像素格式 (如 pf32bit)。
  • DIB 單元來源:DIB.pas 通常隨 DelphiX 範例提供,或可從網路取得開源實作。

熟練掌握這六種載入方式,能讓遊戲資源管理系統更靈活應對各種美術資源管線需求。

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