Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Поворот Bitmap - а


Страницы:   1 2

chuckloon ©   (2003-10-22 17:16:00) 

Я загрузил Bitmap в TBitmap. Подскажите алгоритм или библиотечку для быстрого поворота его на произвольный угол.


miek   (2003-12-06 20:32:00) [1]

И вот как это выглядит (ипсользую мою библиотеку, но принцип ясен):

var
 t1, t2: pdib;
 sx, sy, i, j, zx, zy: integer;
 z1, z2, xnew, ynew, c, s, fi: single;
 c1, c2: comp;
 p: pointer;
begin
 fi:= -str2int( editbox5.text)*pi/180;

 c:= cos( fi);
 s:= sin( fi);

 for j:= 0 to sy-1 do
   begin
     p:= t2.Scanline[j];
     z1:= -j*s;
     z2:= j*c;
     for i:= 0 to sx-1 do
       begin
         zx:= round( z1);
         zy:= round( z2);
         if (zx>=0) and (zx<sx) and (zy>=0) and (zy<sy) then
           dword( p^):= t1.GetRawPixel( zx, zy);
         z1:= z1+c;
         z2:= z2+s;
         inc( integer( p), 4);
       end;
   end;
end;


miek   (2003-12-06 16:37:00) [2]

Формула работает, и не так уж медленно (без особой оптимизации 70-75 тактов на пиксел). Картинка, конечно, все равно неровная, но зато каждый пиксел приемника проходится по одному разу. Значит, можно будет делать нормальный альфа-блендинг и прочие фокусы.


miek   (2003-12-05 19:22:00) [3]

Спасибо, скоро sпопробую.


MBo   (2003-12-05 07:24:00) [4]

>miek ©   (04.12.03 23:56) [34]

Логика - нужно получить матрицу аффинного преобразования на угол (-Fi) вокруг центра xC,yC
Это произведение матриц переноса на -dx -dy, поворота вокруг 0, обратного переноса. В формулах [1] меняются местами Old и New и знаки при синусах

xOld:=xC+(xNew-xC)*cos(fi)-(yNew-yC)*sin(fi)
yOld:=yC+(xNew-xC)*sin(fi)+(yNew-yC)*cos(fi)

В статье "Поставить точку..." это есть, правда, там еще движение центра по спирали приделано.


miek   (2003-12-04 23:56:00) [5]

Если кто-нибудь знает формулу обратного пересчета координат для поворачиваемого растра (то есть координаты приемника в соответствующие координаты источника), буду очень благодарен.


Yr2   (2003-12-04 19:14:00) [6]

Для всех, кроме этого придурка chuckloon:
- при "простом" пересчёте по формулам, здесь приведенным, изображение выглядит "зубчато". Особенно это заметно при повороте НЕ фотографических изображений, а, например, чертежей, карандашных эскизов и т.п. Для исправления этого эффекта применяются специальные алгоритмы. Некоторые из них реализованы в библиотеке DImageEn фирмы HiComponents, которую можно взять здесь:
http://www.hicomponents.com/zzdownloads_imageen.asp
работает с любыми форматами и много чего умеет.
я не рекламирую. я с ней просто работаю.


chuckloon.   (2003-12-04 15:56:00) [7]

Все бля нах пошли тупые овцеебы...
И ваш полное говно, а иодератор пидор, - сидит целыми днями и срет в рот админу... НИХРЕНА вы не знаете, тупой сайт и все вы уроды..
Короче сосите писю и да прибудет с вами мир....

var
Points: lpPoint;
x0, y0: integer;
w2, h2: integer;
sDIB, dDIB: TDIB;
angle: single;
sDC, dDC: hDC;
begin
sDIB := TDIB.Create;
dDIB := TDIB.Create;
angle := 0;

sDIB.LoadFromFile('notload.bmp');
w2 := sDIB.Width div 2;
h2 := sDIB.Height div 2;

Points[0][0] := Round(-w2*Cos(angle) - h2*Sin(angle) + x0);
Points[0][1] := Round(-w2*Sin(angle) + h2*Cos(angle) + y0);
Points[1][0] := Round(-w2*Cos(angle) + -h2*Sin(angle) + x0);
Points[1][1] := Round(-w2*Sin(angle) - h2*Cos(angle) + y0);
Points[2][0] := Round( w2*Cos(angle) - h2*Sin(angle) + x0);
Points[2][1] := Round( w2*Sin(angle) + h2*Cos(angle) + y0);
}

//sDC := GetDC(Form1.Handle);  <<< если рисовать на это DC то вылазит тоже самое
PlgBlt(dDIB.Canvas.Handle, Points, sDIB.Canvas.Handle, 0,0, 92, 92, 0,0,0);
BitBlt(Form1.Canvas.Handle, 0, 0, 92, 92, sDIB.Canvas.Handle, 0, 0, SrcCopy);
//ReleaseDC(Form1.Handle, sDC);

//  DXPaintBox2.DIB := dDIB;
sDIB.Free;
dDIB.Free;
end;


miek   (2003-12-03 21:48:00) [8]

Тяжелый случай. Еще предложи синус рядом Тэйлора рассчитавать, да. "Мы взяли еще Фанты и тормознули крутейший Пень-4"...


A_nik   (2003-12-03 16:18:00) [9]

Чтобы еще увеличить скорость расчета можно использовать вместо отдельного вызова Sin и Cos одновременный SinCos работает в два раза быстрее (модуль Math).

var
 Sin, Cos: Extended;
begin
 SinCos(angle,Sin,Cos);
 Points[0][0] := Round(-w2*Cos - h2*Sin + x0);
 Points[0][1] := Round(-w2*Sin + h2*Cos + y0);
 Points[1][0] := Round(-w2*Cos + -h2*Sin + x0);
 Points[1][1] := Round(-w2*Sin - h2*Cos + y0);
 Points[2][0] := Round( w2*Cos - h2*Sin + x0);
 Points[2][1] := Round( w2*Sin + h2*Cos + y0);
...
end;


марсианин   (2003-12-02 23:17:00) [10]

угол в радианах!!!!
все точно должно быть.. ты ж положение картинки точками задаешь.. попробуй рисовать точки без картинки

насчет dDIB - размеры задай - ширину, высоту.. и еще глубину цвета.. а то он пустой у тебя.


Micah'GF   (2003-11-30 14:20:00) [11]

посмотри внимательнее - инициализируется и уничтожается.

неуверен в каких единицах должен задаваться угол angle , но если задавать в целых единицах то изображение поворачивается приблизительно (на глаз) на 10-15°..


Micah'GF   (2003-11-30 14:20:00) [12]

посмотри внимательнее - инициализируется и уничтожается.

неуверен в каких единицах должен задаваться угол angle , но если задавать в целых единицах то изображение поворачивается приблизительно (на глаз) на 10-15°..


марсианин   (2003-11-30 12:53:00) [13]

похоже, в том коде что ты привел, dDIB вообще не инициализируешь. размеры хотя бы установил..

что значит "вращение стало линейным"? оно круглое по определению:)


Micah'GF   (2003-11-30 09:28:00) [14]

PlgBlt(Form1.Canvas.Handle, Points, sDIB.Canvas.Handle, 0, 0, sDIB.Width, sDIB.Height, 0,0,0);
вот так заработало!!! и в битмап теперь пишет... незнаю что сделал...
только вот в TDIB.Canvas всеравно не пишет...

ХЫ. как преобразовать angleчтобы вращение стало линейным?


марсианин   (2003-11-29 21:43:00) [15]

а с TBitmap работает? очень удивлюсь если нет.. ХЗ что у тебя там.. я когда писал программу вращения вместо TDIB брал TFastDIB, инициализация - тоже Create и LoadFromFile - все работало на "ура".. попробуй брейк-поинт поставить и посмотреть чему равен dDIB.Canvas.Handle....

короче это тебе домашнее задание:)

зы х0, у0 не забудь проиницЫализировать


Micah'GF   (2003-11-29 13:47:00) [16]

var
 Points: lpPoint;
 x0, y0: integer;
 w2, h2: integer;
 sDIB, dDIB: TDIB;
 angle: single;
 sDC, dDC: hDC;
begin
 sDIB := TDIB.Create;
 dDIB := TDIB.Create;
 angle := 0;

 sDIB.LoadFromFile('notload.bmp');
 w2 := sDIB.Width div 2;
 h2 := sDIB.Height div 2;

Points[0][0] := Round(-w2*Cos(angle) - h2*Sin(angle) + x0);
Points[0][1] := Round(-w2*Sin(angle) + h2*Cos(angle) + y0);
Points[1][0] := Round(-w2*Cos(angle) + -h2*Sin(angle) + x0);
Points[1][1] := Round(-w2*Sin(angle) - h2*Cos(angle) + y0);
Points[2][0] := Round( w2*Cos(angle) - h2*Sin(angle) + x0);
Points[2][1] := Round( w2*Sin(angle) + h2*Cos(angle) + y0);
}

//sDC := GetDC(Form1.Handle);  <<< если рисовать на это DC то вылазит тоже самое
PlgBlt(dDIB.Canvas.Handle, Points, sDIB.Canvas.Handle, 0,0, 92, 92, 0,0,0);
BitBlt(Form1.Canvas.Handle, 0, 0, 92, 92, sDIB.Canvas.Handle, 0, 0, SrcCopy);
//ReleaseDC(Form1.Handle, sDC);

//  DXPaintBox2.DIB := dDIB;
 sDIB.Free;
 dDIB.Free;
end;

вот..


miek   (2003-11-28 16:34:00) [17]

В общем, предлагаю код в студию вынести, а там ясно будет.


марсианин   (2003-11-27 22:30:00) [18]

как битмапы инициализируешь? ничего не забыл? размеры, глубина цвета?


Micah'GF   (2003-11-26 23:12:00) [19]

юзаю TBitmap и TDIB...
если делать так:
PlgBlt(destBitmap.Canvas.Handle, Poin......
то говорят Canvas does not allow drawing,даже когда пытаюсь риовать на канвас формы и с BitBlt тоже самое говорит..
может что то инициализировать\получить\подготовить\... ?!?!?!


марсианин   (2003-11-26 22:27:00) [20]

если юзаешь TBitmap то ничего получать не надо:



var destBitmap, SrcBitmap:TBitmap;
.....................
Points[1][0] := Round( - w2*Cos(angle)  + h2*Sin(angle) + x0); //поправочка:)
....................

PlgBlt(destBitmap.Canvas.Handle, Points, SrcBitmap.Canvas.Handle, 0,0, SrcBitmap.Width, SrcBitmap.Height,0,0,0);


если на АПИ пишешь, могу написать конечно, но неуверен что поможет:)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо