SavtoToFileで上書きエラー?

解決


でるでる  2007-01-16 01:09:59  No: 24478

お世話になります。
ビットマップをSavtoToFileメソッドを使ってセーブするプログラム
を無限ループで行っていると、「EOutOfResourcesクラスに例外を生成しました。'既に存在するファイルを作成することはできません'」という
メッセージが表示しプログラムが終了してしまいます。
そして出来たファイルをみるとサイズが0KBで作成されています。(中は
開けませんが...)
SavtoToFileメソッドは同ファイルがあった場合、削除してから記録すると書いてあるのでこのメッセージの意味がわかりません。
考えられる事を教えて下さい。
これだけではなんともいえないのなら、ソースを見てもらいたいのです...(長いのですが)


でるでる  2007-01-16 17:53:55  No: 24479

自己レスです。
ソースです。
procedure TForm1.Button1Click(Sender: TObject);
var
  BaseBmp, OverBmp:   TBitmap;
  ImagePath:          String;
  ExePath:            String;
  BaseBmpFname:       String;
  OverBmpFname:       String;
  AfterBMPFname:      String;
  fd:                  Integer;
  BaseXSize,BaseYSize:Integer;
  OverXSize,OverYSize:Integer;
begin
  flg := 0;
  Repeat
    Application.ProcessMessages;
    ExePath  := ExtractFilePath(Application.ExeName);
    AfterBMPFname:= ExePath + 'Afetr.BMP';
    BaseBmpFname := ExePath + 'Before.BMP';
    OverBmpFname := ExePath + '目安2.BMP';
    //
    BaseBmp := TBitmap.Create;
    OverBmp := TBitmap.Create;

    // 重ねられるイメージを読込み--(1)BaseBmp
    BaseBmp.LoadFromFile(BaseBmpFname);
    //重ねられるイメージの[高さ、幅]の情報を得る
    BaseXSize := BaseBmp.Width;
    BaseYSize := BaseBmp.Height;

    // 重ねるイメージを読込み--(2)    OverBmp
    OverBmp.LoadFromFile(OverBmpFname);
    //重ねるイメージの[高さ、幅]の情報を得る
    OverXSize := OverBmp.Width;
    OverYSize := OverBmp.Height;

    // (2)のイメージ全体を(1)のイメージの位置(左上)に重ねる//左上
    BaseBmp.Canvas.CopyRect(Rect(0,0,OverXSize,OverYSize),
    OverBmp.Canvas,Rect(0,0,OverXSize,OverYSize));

    // (2)のイメージ全体を(1)のイメージの位置(右上)に重ねる//右上
    BaseBmp.Canvas.CopyRect(Rect(BaseXSize-  OverXSize,0,BaseXSize,OverYSize),
           OverBmp.Canvas,Rect(0,0,OverXSize,OverYSize));

    // (2)のイメージ全体を(1)のイメージの位置(左下)に重ねる//左下
    BaseBmp.Canvas.CopyRect(Rect(0,BaseYSize-OverYSize,OverXSize,BaseYSize),
           OverBmp.Canvas,Rect(0,0,OverXSize,OverYSize));

    // (2)のイメージ全体を(1)のイメージの位置(右下)に重ねる//右下
    BaseBmp.Canvas.CopyRect(Rect(BaseXSize-OverXSize,BaseYSize-OverYSize,BaseXSize,BaseYSize),
           OverBmp.Canvas,Rect(0,0,OverXSize,OverYSize));

    // どうなったか?確認してみる
    Canvas.Draw(5,10,BaseBmp);

    Sleep(10);       

    //記録
    BaseBmp.SaveToFile(AfterBMPFname);

    BaseBmp.Free;
    OverBmp.Free;

  Until flg = 1;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
  Close;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
   flg := 1;
end;

Sleep(10)は関係ないかもしれません。


えーとね  2007-01-16 20:40:49  No: 24480

Delphi2006 Update2 で上記コードを実行。
1分程度、放置してみましたが、何も起きませんでした。

> 考えられる事を教えて下さい。
システム・リソース不足でしょうか。

Free する前にDormant, FreeImage, ReleaseHandle メソッドを実行してみたら、どうでしょう。


でるでる  2007-01-16 20:48:08  No: 24481

えーとねさん、ありがとうございます。
>1分程度、放置してみましたが、何も起きませんでした。
1時間後に起きたり、5時間後に起きたりします。
具体的な原因箇所がわかりました。
SaveToFileメソッド先でエラーが起こり,戻り値がFALSEになります。

>システム・リソース不足でしょうか。
落ちる時間が不定なので、どうなんでしょうか?

>Free する前にDormant, FreeImage, ReleaseHandle メソッドを実行してみたら、どうでしょう。
SaveToFileメソッド先でエラーが起こっています。ネットでみてもSaveToFileで例外処理ってあまり書いてないのですが、する事自体が
不思議です。


でるでる  2007-01-16 20:54:21  No: 24482

えーとねさんへ。訂正です。
>Free する前にDormant, FreeImage, ReleaseHandle メソッドを実行してみたら、どうでしょう。
実行してみます。


deldel  2007-01-16 21:53:36  No: 24483

ファイル保存がコード的には完了していても、
実際はハードディスク上にファイルが完全には
できてないという現象に遭ったことがあります。
腑に落ちなかったのですが、仕方が無いので
ファイル保存後、完全にファイルができたか
ファイルサイズを調べて対応しました。
Windowsならこんなこともあったということで・・・。


でるでる  2007-01-17 00:11:36  No: 24484

>Free する前にDormant, FreeImage, ReleaseHandle メソッドを実行してみたら、どうでしょう。
変わらなかったです。(ヘルプの記述をしました。)

deldelさん、ありがとうございます。
自分もSaveToFileでFALSEになったらもう一度SaveToFileをする処理(TRUEになるまで)を入れました。結果失敗しても2回目で成功するなど書き込みは
出来ました。


でるでる  2007-01-25 01:31:51  No: 24485

自己レスです。
TBITMAPを使わないで、メモリ上で直接ピクセルデータを変更する方法で
エラーが出なくなりました。
グラフィックメモリの確保の仕方に違いがあるのでしょうか?


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

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






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