ビットマップを回転描画する例は、いくつか紹介されていますが、例えば、
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;
アルゴリズムを改めるべきでは?
1.ソースを回転 → それをソースに保存
2.以下1を繰り返し・・・
とするからNGなのであって、
あくまでもソース(オリジナル)は退避しておかなくては。
そうしないと、サイズもどんどん大きくなるけど、それ以上に画質がどんどん劣化します。
ウォレスさん、早速ありがとうございます。
ソースを保存し、作業用Bitmapを作り・・・と、やっては見たのですが、
1.ソースを回転 →(余白が)大きくなる→それをソースに保存
2.以下1を繰り返し・・・ →さらに(余白が)大きくなる。
>アルゴリズムを改めるべきでは?
>そうしないと・・・
もう少しヒントをいただけるとあり難いのですが、よろしくお願いします。
たぶんです。
正方形の画像で試してみてください。
うまくいくとおもいます。
> 1.ソースを回転 →(余白が)大きくなる→それをソースに保存
これ、NGだとウォレスさんが回答されてますよ。
ソースと表示用のBitmapを用意し、例えば、
1)30度右回転
2)さらに45度左回転
であれば、
1)ソースから30度右回転した画像を作成し表示
2)ソースから現在の回転角30を引いた15度左回転した画像を作成し表示
ちゅうことでしょ?
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;
考えているうちに・・・皆さんコメントありがとうございます。
「手トリス足とりす」さんには、お手本を示していただきまして大変ありがとうございます。
時間が掛かりますが、理解し消化して使わせていただきます。
自分成りに改良案を考えていました。ボツになりますが・・・
回転用のボタンの隣に角度入力用の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.
「手トリス足とりす」さん
余計な余白なく、ぐるぐる回りました。
TetoriAsitoris.EXEをディスクトップに置き、勉強させていただきます。
皆さん、ありがとうございました。
考え方が分かっていただけたのでしょうか???
例えとして良いかどうかわかりませんが、
もしある文書のコピーを100枚とろうと思ったとき、どうしますか?
先ずオリジナルをコピーし、(それをコピー1と呼ぶ)
次にコピー1を用いてコピー2を作り、
次にコピー2を用いてコピー3を作り、
次にコピー3を用いて・・・・・
としますか?
こんな事をすれば100枚目は見るに耐えない、カスレやボケだらけになってしまいます。
オリジナルからコピー1〜コピー100を作るのではありませんか?
>考え方が分かっていただけたのでしょうか???
入門書の読書もそれなりに面白いのですが、自分のプログラムがしたくなって最近やっと始めました。
実は、数週間前から画像の回転と余白の処理に疑問をもって、自分なりに実験していたんですが、思い切って質問させていただいた次第です。
コピーを繰り返せば画質の劣化が起きることは承知で、ヒントを頂いた時に自分で試せるように質問を用意したつもりでしたが、取りあえずこの疑問を解決する事が出来ました。
皆さんのレベルは高く、質問するにも躊躇していましたが、ウォレスさん、解決ボタンを押してしまった後にも拘らず本当に有り難うございました。
ツイート | ![]() |