![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Поворот Bitmap - а
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);
если на АПИ пишешь, могу написать конечно, но неуверен что поможет:)