画像の回転後のサイズを制限するには?

解決


HMMA  2008-02-21 04:44:29  No: 29855

ビットマップを回転描画する例は、いくつか紹介されていますが、例えば、
http://wblue.web.infoseek.co.jp/lec/one/04/o004a.htm
procedure RotateImage(Bitmap: TBitmap; const Angle: Extended);
・・・の「画像の自由角度回転」を使わせていただいて、
下のように呼ぶと、ちゃんと回転して表示してくれるのですが、
この回転を繰り返すと、回転後の画像がどんどん大きくなります。

最大(制限値)を決めて置くのかな・・・とも思いましたが、
おそらく何か良い方法があるのでしょうね?
そんな方法を教えていただきたくて質問します。
よろしくお願いします。(Delphi6Pro+winXP)

procedure TForm1.Button2Click(Sender: TObject);
var agl:  Extended;
begin
  agl:=30;  //回転角
  RotateImage(Bitmap,agl);
  Image1.Picture.Bitmap := Bitmap;
  Button2.Enabled:=True;
end;


ウォレス  2008-02-21 18:48:19  No: 29856

アルゴリズムを改めるべきでは?

1.ソースを回転  →  それをソースに保存
2.以下1を繰り返し・・・

とするからNGなのであって、
あくまでもソース(オリジナル)は退避しておかなくては。

そうしないと、サイズもどんどん大きくなるけど、それ以上に画質がどんどん劣化します。


HMMA  2008-02-21 20:24:21  No: 29857

ウォレスさん、早速ありがとうございます。

ソースを保存し、作業用Bitmapを作り・・・と、やっては見たのですが、

1.ソースを回転  →(余白が)大きくなる→それをソースに保存
2.以下1を繰り返し・・・  →さらに(余白が)大きくなる。

>アルゴリズムを改めるべきでは?
>そうしないと・・・
もう少しヒントをいただけるとあり難いのですが、よろしくお願いします。


たぶん  2008-02-21 20:59:22  No: 29858

たぶんです。
正方形の画像で試してみてください。
うまくいくとおもいます。


ofZ  2008-02-21 21:12:17  No: 29859

> 1.ソースを回転  →(余白が)大きくなる→それをソースに保存
これ、NGだとウォレスさんが回答されてますよ。

ソースと表示用のBitmapを用意し、例えば、
1)30度右回転
2)さらに45度左回転
であれば、
1)ソースから30度右回転した画像を作成し表示
2)ソースから現在の回転角30を引いた15度左回転した画像を作成し表示

ちゅうことでしょ?


手トリス足とりす  2008-02-21 21:50:20  No: 29860

var
  bmp: TBitmap;
  Angle: Extended;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  Button1.Enabled := False;
  for i:=1 to 300 do begin
   Image1.Picture.Bitmap.Assign(bmp);
   Angle := Angle + Pi / 3;                   // π/3単位で回転
   RotateImage(Image1.Picture.Bitmap, Angle);
   Image1.Width := Image1.Picture.Bitmap.Width;
   Image1.Height := Image1.Picture.Bitmap.Height;
   Application.ProcessMessages; Sleep(200);
   if GetKeyState(VK_ESCAPE) < 0 then break;;
  end;
  Button1.Enabled := True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Form1.DoubleBuffered := True;
  bmp := TBitmap.Create;
  bmp.LoadFromFile('C:\My Documents\My Pictures\822p1_393x400.bmp');
  Image1.Picture.Bitmap.Assign(bmp);
  Image1.Width := Image1.Picture.Bitmap.Width;
  Image1.Height := Image1.Picture.Bitmap.Height;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  bmp.Free;
end;


HMMA  2008-02-22 00:02:07  No: 29861

考えているうちに・・・皆さんコメントありがとうございます。
「手トリス足とりす」さんには、お手本を示していただきまして大変ありがとうございます。
時間が掛かりますが、理解し消化して使わせていただきます。

自分成りに改良案を考えていました。ボツになりますが・・・
回転用のボタンの隣に角度入力用のEdit1を置き、作業用のTmpBmpを用意

procedure TForm1.Button2Click(Sender: TObject);
var
 agl,agl2:  Extended;
begin
 begin
  If {最初の回転}then  //考え中
  begin
  agl:=StrToFloat(Edit1.Text);  //回転角
  agl2:=agl;
  end
  else
   {2回目以降の回転}
   agl:=StrToFloat(Edit1.Text)+agl2; //追加回転角
 end;
  Bitmap.Assign(TmpBmp);
  RotateImage(Bitmap,agl);
  Image1.Picture.Bitmap := Bitmap;
  ShowMessage(FloatToStr(agl));
   end;

end.


HMMA  2008-02-22 01:26:08  No: 29862

「手トリス足とりす」さん
余計な余白なく、ぐるぐる回りました。
TetoriAsitoris.EXEをディスクトップに置き、勉強させていただきます。

皆さん、ありがとうございました。


ウォレス  2008-02-22 03:18:15  No: 29863

考え方が分かっていただけたのでしょうか???

例えとして良いかどうかわかりませんが、

もしある文書のコピーを100枚とろうと思ったとき、どうしますか?
先ずオリジナルをコピーし、(それをコピー1と呼ぶ)
次にコピー1を用いてコピー2を作り、
次にコピー2を用いてコピー3を作り、
次にコピー3を用いて・・・・・
としますか?

こんな事をすれば100枚目は見るに耐えない、カスレやボケだらけになってしまいます。

オリジナルからコピー1〜コピー100を作るのではありませんか?


HMMA  2008-02-22 07:27:54  No: 29864

>考え方が分かっていただけたのでしょうか???

入門書の読書もそれなりに面白いのですが、自分のプログラムがしたくなって最近やっと始めました。
実は、数週間前から画像の回転と余白の処理に疑問をもって、自分なりに実験していたんですが、思い切って質問させていただいた次第です。
コピーを繰り返せば画質の劣化が起きることは承知で、ヒントを頂いた時に自分で試せるように質問を用意したつもりでしたが、取りあえずこの疑問を解決する事が出来ました。
皆さんのレベルは高く、質問するにも躊躇していましたが、ウォレスさん、解決ボタンを押してしまった後にも拘らず本当に有り難うございました。


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

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






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