ビットマップとテキストを1つのファイルに保存したいのですが

解決


たま  2009-12-13 07:53:50  No: 36428

皆様お世話になります
早速ですが・・・
タイトル通りなのですが ビットマップとテキストを1つのファイルに保存できないでしょうか?
ビットマップは16*16
テキストのサイズは不定です。

D7 WinXP

よろしくお願い致します。


mook  2009-12-13 19:34:06  No: 36429

こんなのはどうでしょう。
私がWEB関連で良く使う手法です。

Base64encode/decodeなどの変換ライブラリーを使いまして。
(バイナリーの扱えるライブラリーが必要)

text=xxxxxxx(Base64encode変換した文字列)xxxxxxxxxxxx\n
bitmap=xxxxxxx(Base64encode変換した画像データ)xxxxxxxxxxxx\n

簡単に説明しますと、Base64等で変換し規定の文字列に
変換することで区分けが出来て扱いやすくなると言うものです。
(特に巨大なデータでなければサイズも余り考えなくても良いかと・・)

これであればいろんな種類を自由に混ぜ込むことが出来ます。


monaa  2009-12-13 21:34:03  No: 36430

意外と簡単に実装可能です。
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure LoadTBStream(var aStream:TStream; var Txt:string; var Bmp:TBitmap);
var
  size:Integer;
begin
  aStream.Position:=0;
  aStream.Read(size,SizeOf(Integer));
  SetLength(Txt,size div SizeOf(Char));
  aStream.read(Txt[1], size-1);
  Bmp.LoadFromStream(aStream);
end;

procedure SaveTBStream(var aStream:TStream; var Txt:string; var Bmp:TBitmap);
var
  size:Integer;
begin
  aStream.Position:=0;
  size := Length(Txt) * SizeOf(Char);
  aStream.Write(size, SizeOf(Integer));
  aStream.Write(Txt[1],size-1);
  Bmp.SaveToStream(aStream);
end;

procedure LoadTB(FileName:string; var Txt:string; var Bmp:TBitmap);
var
  aStream:TMemoryStream;
begin
  aStream := TMemoryStream.Create;
  aStream.LoadFromFile(FileName);
  LoadTBStream(TStream(aStream), Txt, Bmp);
  aStream.Free;
end;

procedure SaveTB(FileName:string; var Txt:string; var Bmp:TBitmap);
var
  aStream:TMemoryStream;
begin
  aStream := TMemoryStream.Create;
  SaveTBStream(TStream(aStream), Txt, Bmp);
  aStream.SaveToFile(FileName);
  aStream.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  bmp:TBitmap;
  txt:string;
begin
  bmp := TBitmap.Create;
  bmp.LoadFromFile('test.bmp');
  txt := Memo1.Text;
  SaveTB('test.tbf',txt,bmp);
  bmp.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  bmp:TBitmap;
  txt:string;
begin
  bmp := TBitmap.Create;
  LoadTB('test.tbf',txt,bmp);
  Canvas.Draw(0,0,bmp);
  Memo1.Text:=txt;
  bmp.Free;
end;

end.


Mr.XRAY  2009-12-13 23:02:20  No: 36431

Mr.XRAYです.
monaaさんのコードがシンプルでいいと思いますが,

>これであればいろんな種類を自由に混ぜ込むことが出来ます。

ということで私も1つの方法として.
Delphiのクラスを使用した方法です.データを格納するクラスを用意します.
いろいろな型のプロパティが追加できます.

//=============================================================================
//  変数やオブジェクト型の保存読出しの一つの方法
//  Presented by Mr.XRAY
//=============================================================================
unit Unit1;

interface

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

type
  //目的のデータを格納するクラス
  TData = class(TComponent)
  private
    FText : String;
    FBitmap : TBitmap;
    procedure SetBitmap(const Value: TBitmap);
  protected
  public
    constructor Create(AOwner: TComponent);override;
    destructor Destroy; override;
  published
    property Text   : String  read FText   write FText;
    property Bitmap : TBitmap read FBitmap write SetBitmap;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Memo1: TMemo;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private 宣言 }
    TestData  : TData;
    AFileName : TFileName;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

{ TData }

//-----------------------------------------------------------------------------
//  TDataクラスのCreate
//  オブジェクト型のプロパティはここで生成
//-----------------------------------------------------------------------------
constructor TData.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FBitmap := TBitmap.Create;
end;

//-----------------------------------------------------------------------------
//  TDataクラスのDestroy
//  生成したオブジェクトを破棄
//-----------------------------------------------------------------------------
destructor TData.Destroy;
begin
  FreeAndNil(FBitmap);
  inherited;
end;

//-----------------------------------------------------------------------------
//  オブジェクト型の設定メソッド
//-----------------------------------------------------------------------------
procedure TData.SetBitmap(const Value: TBitmap);
begin
  if Value<>nil then
    FBitmap.Assign(Value);
end;

//=============================================================================
//  Formを生成したらTDataクラスのオブジェクトTestDataも生成
//  AFileNameは保存ファイル名
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  TestData  := TData.Create(Self);
  AFileName := ExtractFilePath(Application.ExeName) + 'ATest.dat';
end;

//=============================================================================
//  動作確認用のデータをセット
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  if Assigned(TestData) then
  begin
    TestData.Bitmap.LoadFromFile('Samp1.bmp');
    TestData.Text := 'テスト文字列';

    //セットしたデータを表示
    Image1.Picture := nil;
    Memo1.Lines.Clear;
    Image1.Picture.Assign(TestData.Bitmap);
    Memo1.Lines.Add(TestData.Text);
  end;
end;

//=============================================================================
//  現在のデータを保存
//  WriteComponentだけでOK
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  FileStream : TFileStream;
begin
  FileStream := TFileStream.Create(AFileName,fmCreate);
  try
    if Assigned(TestData) then
      FileStream.WriteComponent(TestData);
  finally
    FreeAndNil(FileStream);
  end;
end;

//=============================================================================
//  保存してあるデータを読出して表示
//  ReadComponentだけでOK
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
  FileStream : TFileStream;
begin
  if not FileExists(AFileName) then
    exit;

  if Assigned(TestData) then
    FreeAndNil(TestData);

  TestData   := TData.Create(Self);
  FileStream := TFileStream.Create(AFileName,fmOpenRead);
  try
    FileStream.ReadComponent(TestData);
  finally
    FreeAndNil(FileStream);
  end;

  //読出したデータを表示
  Image1.Picture := nil;
  Memo1.Lines.Clear;
  Image1.Picture.Assign(TestData.Bitmap);
  Memo1.Lines.Add(TestData.Text);
end;


たま  2009-12-14 02:02:15  No: 36432

mookさま、monaaさま、Mr.XRAYさま、
ありがとうございます。

親切に教えていただいたので、ご好意を無駄にせず、全部試して見ます。

本当にありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加