2015-08-11 3 views
2

Мне нужно нарисовать повернутое растровое изображение на холсте другого растрового изображения (основной растровый рисунок). Но я понятия не имею, как это сделать.Рисование повернутых растровых изображений на холсте

Я попытался повернуть растровое изображение с помощью метода TBitMap.Rotate, а затем сделать его основным BitMap с методом TCanvas.DrawBitmap, но это занимает много времени (мне нужно сделать ~ 100 же Bitmaps с различными углами):

  1. размер BMP
  2. вращать BMP
  3. рисовать на другом холсте

Как сразу нарисовать повернутый растровое без 1 и 2 шага?

Пример:

var 
    Form1: TForm1; 
    MainBMP: TBitMap; 
    SomeItem: TBitMap; 
    buffBMP: TBitMap; 

implementation 

{$R *.fmx} 


procedure TForm1.FormCreate(Sender: TObject); 
begin 
    MainBMP := TBitMap.Create; 
    MainBMP.SetSize(screen.Width, screen.Height); 
    SomeItem := TBitMap.Create; 
    SomeItem.SetSize(50, 50); 
    with SomeItem.Canvas do 
    begin 
    BeginScene; 
    FillRect(rectF(0, 0, 50, 50), 5, 20, allCorners, 1); 
    EndScene; 
    end; 
    buffBMP := TBitMap.Create; 
end; 

procedure TForm1.Timer1Timer(Sender: TObject); 
var 
    i: integer; 
    rect, sizeRect: TRectF; 
begin 
    MainBMP.Canvas.BeginScene; 
    MainBMP.Canvas.Clear($FF777777); 
    for i := 1 to 10000 do 
    begin 
    buffBMP.Assign(SomeItem); 
    buffBMP.Rotate(random(360)); 
    sizeRect := rectF(0, 0, buffBMP.Width, buffBMP.Height); 
    rect := sizeRect; 
    rect.Offset(random(1200), random(600)); 
    MainBMP.Canvas.DrawBitmap(buffBMP, sizeRect, rect, 1); 
    end; 
    MainBMP.Canvas.EndScene; 
    Form1.Canvas.BeginScene; 
    Form1.Canvas.DrawBitmap(MainBMP, ClientRect, ClientRect, 1); 
    Form1.Canvas.EndScene; 
end; 

без

buffBMP.Rotate(random(360)); 

это занимает 16-32 мс. С помощью этого метода: ~ 8500 мс

Я ищу какой-то метод, как

TCanvas.DrawBitmap(const ABitmap: TBitmap; const SrcRect, DstRect: TRectF; const AOpacity: Single; const HighSpeed: Boolean); 

, но с добавлением Угол обзора: одиночный Parametr

Android. FMX.

Спасибо.

+0

Ниже приведены примеры растровых вращения с помощью Scanline http://www.efg2.com/Lab/ImageProcessing/Unit7.TXT –

+0

@JasperSchellingerhout это только 180, 90 и 270 Мне нужно вращаться на дробных углах, например 12,5, 186,23 и т. Д. –

+0

Какая скорость вам нужна, и какое разрешение и битдент являются изображениями? что является узким местом? изменение размера целевого изображения должно быть быстрым вращением - это просто копирование пикселей + преобразование вращения, которое требует: 1x 'cos', 1x' sin' 4x '*' и 2x '+/-' в FPU, затем 2 преобразования в 'int', которые должны быть достаточно быстро (если вы также используете билинейную фильтрацию, это немного медленнее, но не так много), вы должны пропустить все пиксели назначения, а не исходные, чтобы избежать отверстий в выходе. – Spektre

ответ

2

Вы должны использовать преобразование Matrix вместо метода Rotate на растровом изображении.

Такое может выглядеть следующим образом:

procedure TForm1.Timer1Timer(Sender: TObject); 
var 
    I: Integer; 
    R: TRectF; 
    SaveMatrix: TMatrix; 
    Matrix: TMatrix; 
begin 
    MainBMP.Canvas.BeginScene; 
    MainBMP.Canvas.Clear($FF777777); 
    SaveMatrix := MainBmp.Canvas.Matrix; 
    for I := 1 to 1000 do 
    begin 
    BuffBMP.Assign(SomeItem); 
    R := RectF(0, 0, BuffBMP.Width, BuffBMP.Height); 
    Matrix := CreateRotationMatrix(DegToRad(Random(360))); 
    Matrix.m31 := Random(1200); 
    Matrix.m32 := Random(600); 
    MainBMP.Canvas.SetMatrix(Matrix); 
    MainBMP.Canvas.DrawBitmap(buffBMP, R, R, 1, True); 
    end; 
    MainBMP.Canvas.SetMatrix(SaveMatrix); 
    MainBMP.Canvas.EndScene; 
    Canvas.BeginScene; 
    Canvas.DrawBitmap(MainBMP, ClientRect, ClientRect, 1); 
    Canvas.EndScene; 
end; 
+0

Большое спасибо! :) –

Смежные вопросы