3

こんにちは。

私は、ユーザーがビットマップをロードしたTImageをキャンバス上にドラッグアンドドロップできる描画プログラムに取り組んでいます。(RAD StudioXE2のFiremonkeyHDアプリケーションの場合)ユーザーは、画像を保存する前に、xとyのスケールと回転を変更できます。すべてのTImageはリストに保持され、このリストは次の簡単な手順を使用して基になるキャンバスに書き込まれます。

  for i := 0 to DroppedList.Count - 1 do
  begin
    AImage := DroppedList[i];
    SourceRect.Left := 0;
    SourceRect.Right := AImage.Bitmap.Width;
    SourceRect.Top := 0;
    Sourcerect.Bottom := AImage.Bitmap.Height;

    TargetRect.Left := AImage.Position.X;
    TargetRect.Right := AImage.Position.X + AImage.Bitmap.Width;
    TargetRect.Top := AImage.Position.Y;
    TargetRect.Bottom := AImage.Position.Y + AImage.Bitmap.Height;

    with FImage.Bitmap do
    begin
      Canvas.BeginScene;
      Canvas.DrawBitmap(AImage.Bitmap, SourceRect, TargetRect, 1, True);
      Canvas.EndScene;
      BitmapChanged
    end;
  end;

  FImage.Bitmap.SaveToFile('test.bmp');

これに伴う問題は、ウィンドウに表示されている画像の縮尺と回転への変換がDrawBitmapによって考慮されず、保存時に失われることです。背景に描画する前に、ビットマップに変換を適用する方法を探しています。私はこれに関する情報を見つけることができなかったので、私はここの誰かが助けてくれることを望んでいました。

ありがとう、ダニエル

4

1 に答える 1

2

問題は、スケーリングと回転がソースTImageに適用されていることのようです。この「ソースTImage」では、変換はビットマップに対して行われるのではなく、TImageレベルで行われます(これはTControlであり、すべてのTControlとして、スケーリングおよび回転できるため)。後でソースビットマップを別の場所にコピーしますが、実際にはこのビットマップは変更されていません

したがって、ソースTImageの設定に従って、ループ内のビットマップを回転およびスケーリングする必要があります。

with FImage.Bitmap do
begin
  Canvas.BeginScene;     
  LBmp := TBitmap.Create;
  try
    // create a copy on which transformations will be applyed
    LBmp.Assign(AImage.Bitmap); 
    // rotate the local bmp copy according to the source TImage.
    if AImage.RotationAngle <> 0 then
      LBmp.Rotate( AImage.RotationAngle);
    // scale the local bmp copy...
    If AImage.Scale.X <> 1 
      then ;
    Canvas.DrawBitmap(LBmp, SourceRect, TargetRect, 1, True);
  finally
    LBmp.Free;
    Canvas.EndScene;
    BitmapChanged
  end;
end;

この単純なコードサンプルは、問題をよく説明しています。たとえば、RotatationAngleはAImageのプロパティであり、AImage.Bitmapのプロパティではありませ

変換の実装を回避する回避策は、TControl.MakeScreenshot()を使用することです。(確認のため、これは失敗する可能性があります)

with FImage.Bitmap do
begin
  Canvas.BeginScene;
  LBmpInclTranformations := AImage.MakeScreenShot;
  Canvas.DrawBitmap(LBmpInclTranformations, SourceRect, TargetRect, 1, True);
  Canvas.EndScene;
  BitmapChanged
end;
于 2012-09-01T15:27:46.330 に答える