お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"Q0ファイルを表示する"



こんにちは。fumikaです。


Q0 や RGB といったフルカラーベタの画像ファイルを表示させる
ためのグラフィッククラスです。以下を Q0Bmp.pas という名前で
保存して uses に加えるだけで、TImage などに表示することが
できるようになります。汚いソースですがご参考までに。
あまりテストしてません(^^;)

-------------------- >8 キリトリ ---------------------------------------
unit Q0Bmp;

{$IFDEF VER90}
  need Delphi3 later
{$ENDIF}
{$IFDEF VER93}
  need C++Builder3 later
{$ENDIF}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, 
Dialogs;

type
  TQ0Bitmap = class(TBitmap)
  public
    procedure LoadFromFile(const FileName: string); override;
  end;

procedure Register;

implementation

{  TQ0Bitmap  }

procedure TQ0Bitmap.LoadFromFile(const FileName: string);
var
  Ext, InfoFileName, S, SizeStr: string;
  SL: TStringList;
  Stream1, Stream2: TMemoryStream;
  BFH: TBitmapFileHeader;
  BIH: TBitmapInfoHeader;
  Buff: array[1..3] of Byte;
  BX, FW, FH: LongInt;
  X, Y: Integer;
begin
  try
    Ext := AnsiLowerCase(ExtractFileExt(FileName));
    // 拡張子が .Q0 のファイルの場合、 .FAL ファイルに
    // 画像のサイズが格納されている(らしい)。
    if Ext = '.q0' then begin
      InfoFileName := ChangeFileExt(FileName, '.fal');
      if not FileExists(InfoFileName) then
        raise Exception.Create('FAL ファイルが見つかりません');
      SL := TStringList.Create;
      try
        SL.LoadFromFile(InfoFileName);
        if Copy(SL[0], 0 ,5) <> 'F_ALL' then begin
          MessageBeep(MB_ICONHAND);
          MessageDlg('FAL ファイルが不正です', mtError, [mbOk], 0);
          Exit;
        end;
        SizeStr := SL[1];
      finally
        SL.Free;
      end;
    end else
    // 拡張子が .RGB のファイルの場合、 .IPR ファイルに
    // 画像のサイズが格納されている(らしい)。
    if Ext = '.rgb' then begin
      InfoFileName := ChangeFileExt(FileName, '.ipr');
      if not FileExists(InfoFileName) then
        raise Exception.Create('IPR ファイルがありません');
      SL := TStringList.Create;
      try
        SL.LoadFromFile(InfoFileName);
        SizeStr := SL.Text;
      finally
        SL.Free;
      end;
    end;
    // .FAL or .IPR ファイルから読みとった文字列から、
    // 画像の幅、高さを切り出す。
    SizeStr := TrimLeft(SizeStr);
    S  := Copy(SizeStr, 0, Pos(' ', SizeStr) - 1);
    FW := StrToIntDef(S, 0);
    SizeStr := TrimLeft(Copy(SizeStr, Length(S) + 1, 
                             Length(SizeStr)-Length(S)));
    FH := StrToIntDef(Copy(SizeStr, 0, Pos(' ', SizeStr) - 1), 0);
  except
    FW := 0;
    FH := 0;
  end;

  // DIB データ作成用ストリームの作成
  Stream1 := TMemoryStream.Create;
  try
    // BITMAPINFOHEADER の作成
    BIH.biSize := SizeOf(TBitmapInfoHeader);
    BIH.biWidth  := FW;
    BIH.biHeight := FH;
    BIH.biPlanes := 1;
    BIH.biBitCount := 24;
    BIH.biCompression := BI_RGB;
    BIH.biClrUsed := 0;
    BIH.biClrImportant := 0;
    BX := ((LongInt(BIH.biWidth) * BIH.biBitCount + 31) div 32) * 4;
    BIH.biSizeImage := BX * BIH.biHeight;

    // ビットデータ読み込み用ストリームの作成
    Stream2 := TMemoryStream.Create;
    try
      Stream2.LoadFromFile(FileName);

      // 幅、高さが 0 の場合、ここでファイルサイズから
      // 適当に割り出す。
      if BIH.biSizeImage = 0 then begin
        BIH.biSizeImage := Stream2.Size;// div 3;
        if (BIH.biWidth = 0) and (BIH.biHeight = 0) then begin
          if BIH.biSizeImage div 3 = 256000 then begin
            BIH.biHeight := 400;
            BIH.biWidth  := 640;
          end else begin
            BIH.biHeight := (BIH.biSizeImage div 3) div 640;
            BIH.biWidth  := 640;
          end;
          BX := ((LongInt(BIH.biWidth) * BIH.biBitCount + 31) div 32) * 4;
        end else begin
          if BIH.biHeight <> 0 then
            BIH.biWidth  := Longint(BIH.biSizeImage) div BIH.biHeight
          else
            BIH.biHeight := Longint(BIH.biSizeImage) div BIH.biWidth;
        end;
      end;

      // BITMAPFILEHEADER の作成
      BFH.bfType := $4D42;
      BFH.bfSize := (SizeOf(TBitmapFileHeader)
                  + SizeOf(TBItmapInfoHeader)
                  + Stream2.Size) div 4;
      BFH.bfReserved1 := 0;
      BFH.bfReserved2 := 0;
      BFH.bfOffBits  := SizeOf(TBitmapFileHeader) + SizeOf(TBItmapInfoHeader);

      // BITMAPFILEHEADER の書き込み
      Stream1.Write(BFH, SizeOf(TBitmapFileHeader));

      // BITMAPINFOHEADER の書き込み
      Stream1.Write(BIH, SizeOf(TBitmapInfoHeader));

      for Y := 0 to BIH.biHeight - 1  do begin
        // Bitmap はボトムアップなのでデータはファイルの後ろの
        // 方から読み出す。
        Stream2.Seek(-BX * Y, soFromEnd);
        for X := 0 to (BIH.biWidth - 1) do begin
          // フルカラーベタファイルは RGB 順、Bitmap は BGR 順なので
          // 書き換えながらビットデータを作成。
          Stream2.Read(Buff, 3);
          Stream1.Write(Buff[3], 1);
          Stream1.Write(Buff[2], 1);
          Stream1.Write(Buff[1], 1);
        end;
      end;
    finally
      Stream2.Free;
    end;

    Stream1.Position := 0;
    inherited LoadFromStream(Stream1);
  finally
    Stream1.Free;
  end;
end;

{  初期化部  }

procedure Register;
begin
  // 何もしないが設計時に使われるために削除しないこと
end;

initialization
  TPicture.RegisterFileFormat('q0', 'フルカラーベタ', TQ0Bitmap);
  TPicture.RegisterFileFormat('rgb', 'フルカラーベタ', TQ0Bitmap);

finalization
  TPicture.UnregisterGraphicClass(TQ0Bitmap);

end.
-------------------- >8 キリトリ ---------------------------------------


    平成10年12月2日(水)  fumika(YRK00111@nifty.ne.jp)
         ★☆★ http://www2m.biglobe.ne.jp/~fumika/ ★☆★

Original document by fumika    氏 ID:(YRK00111)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum