Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.24;
Скачать: CL | DM;

Вниз

Как, не испортив изображения, повернуть прямоугольник в TImage   Найти похожие ветки 

 
LicProd   (2004-10-08 17:18) [0]

Спасибо всем, что "помогли" мне разобраться с вопросом о Хэндле Тулбара! Я его сам уже решил, очень даже красиво!

Так вот теперь очередной вопрос! :)

Как можно качественно повернуть изображение?
Если я поворачиваю его попиксельно или полинейно, то получаются небольшие просветы! Я не говорю про красочные рисунки!

К примеру как качественно повернуть изображение TImage в котором нарисован простой чёрный ПРЯМОУГОЛЬНИК

З.Ы.:  Есть одна компанента такая Graphics32 помоему так называется, но она никак не хочет союзничать с моей программой!


 
MBo ©   (2004-10-08 17:30) [1]

Для каждой точки нового рисунка рассчитывай соотв. координаты в старом


 
LicProd   (2004-10-08 17:51) [2]

Это значит мне надо накладывать одно изображение на предыдущее???
Я не понимаю!


 
MBo ©   (2004-10-08 17:58) [3]

покажи, как ты поворачиваешь


 
LicProd   (2004-10-08 18:14) [4]

Запросто!
------
RTBMPR:TBitmap;
RTAngle:integer;

-----
Function TurnAngle(const tk,tn:TPoint; const Angle:integer):TPoint;
const Pi180 = pi/180;
var f:real;
begin
f := pi180*Angle;
with tk do begin
result.x := round((x - tn.x)*Cos(f)-(y - tn.y)*Sin(f) + tn.x);
result.y := round((x - tn.x)*Sin(f)+(y - tn.y)*Cos(f) + tn.y);
end;
end;

procedure PaintPixel( const p:TPOint; const color:TColor );
begin
изображение.Canvas.Pixels[p.x+50,p.y+50] := color;
end;

procedure ОКНО.FormCreate(Sender: TObject);
begin
RTbmpR:=TBitmap.Create;
end;

procedure ОКНО.PovorotChange(Sender: TObject);
var
scanx,scany:integer;
dest,scanp:TPoint;
begin
Dest := point(RTBMPR.Width div 2, RTBMPR.Height div 2 );
Canvas.Brush.Color:=clwhite;
изображение.Canvas.Rectangle(-1,-1,изображение.Width+1,изображение.Height+1);
scanpos:=Povorot.Position;
//inc(Angle);
for scanx := 1 to RTBMPR.width-1 do
for scany := 1 to RTBMPR.Height-1 do
begin
scanp := TurnAngle(point(scanx,scany),dest,scanpos);
PaintPixel(scanp,RTBMPR.Canvas.Pixels[scanx,scany]);
end;
Application.ProcessMessages;
sleep(10);
end;


не смотри такими большими глазами! просот уже я привык к этой функции, но если есть предложения, я только рад... но это не главное! Главное это вопрос...


 
Fenik   (2004-10-08 18:18) [5]

Моя старенькая процедура:
http://delphibase.endimus.ru/?action=viewfunc&topic=mediaimg&id=10186

Можно ещё немного оптимизировать.


 
Fenik   (2004-10-08 18:22) [6]

По поводу оптимизации. Например yp*ASin и yp*ACos можно вычислять только для новой строки, а не для каждого пиксела.


 
LicProd   (2004-10-08 18:22) [7]

> Fenik
И... т.е. она без искожения поворачивает?
Странно, работает так же как и моя, только твоя пошустрее будет


 
Fenik   (2004-10-08 18:28) [8]

> LicProd  (08.10.04 18:22) [7]
> И... т.е. она без искожения поворачивает?


По крайней мере без просветов :)


 
LicProd   (2004-10-08 18:28) [9]

> Fenik
Нет, извини, твоя процедура орегинальна, но она не решает мою проблему, к сожалению, но всё-равно спасибо!

Как бы быть точным?! Вот к примеру В ACDSee при повороте изображения оно сглаживается! но кроме альясинга там есть ещё что-то, т.к. сглаживается не векторное изображение, как собственно говоря и в моём случае.


 
Fenik   (2004-10-08 18:33) [10]

Может просто сглаживать крайние пиксели?


 
LicProd   (2004-10-08 18:35) [11]

К сожалению я их сглаживать не умею... к сожалению


 
Fenik   (2004-10-08 18:43) [12]

Вот пример сглаживания всего изображения:

procedure AntiAlias(Bitmap: TBitmap);
var x, y: Integer;
   p0, p1, p2: pByteArray;
begin
 for y := 1 to Bitmap.Height - 2 do begin
   p1 := Bitmap.ScanLine[y];
   p0 := Bitmap.ScanLine[y - 1];
   p2 := Bitmap.ScanLine[y + 1];
   for x := 0 to Bitmap.Width - 2 do begin
     p1[x*3]   := (p0[x*3]  +p2[x*3]  +p1[(x-1)*3]  +p1[(x+1)*3]) div 4;
     p1[x*3+1] := (p0[x*3+1]+p2[x*3+1]+p1[(x-1)*3+1]+p1[(x+1)*3+1]) div 4;
     p1[x*3+2] := (p0[x*3+2]+p2[x*3+2]+p1[(x-1)*3+2]+p1[(x+1)*3+2]) div 4;
   end;
 end;
end;


Т.е. находится среднеарифметическое по каждому компоненту цвета для соседей пиксела. Найденное значение присваивается этому пикселу.


 
Fenik   (2004-10-08 18:44) [13]

А попробуй просто вызвать RotateBitmap, а затем AntiAlias.
Может результат будет удовлетворительный? :)


 
LicProd   (2004-10-08 18:56) [14]

О! Уже какой-то есть результат с твоей функцией, но, опять таки! изображение то размывчатое получается! А не должно! Как-будто на него плюнули :)


 
Fenik   (2004-10-08 19:38) [15]

> LicProd  (08.10.04 18:56) [14]

Тогда только крайние пиксели смазывать.


 
Mihey_temporary ©   (2004-10-08 21:37) [16]

Вращение с anti-aliasing:
http://www.efg2.com/Lab/Library/Delphi/Graphics/JackSudarevRotateBitmap.txt


 
LicProd   (2004-10-09 10:39) [17]

> Mihey_temporary ©
Спасибо большое за отпадную программу, но опять таки сути проблемы она не решает!

Попробуй повернуть изображение на 3 градуса с помощью своей программы и ты сам увидишь, что появляются нежеланные эффекты с которыми я так упорно борюсь.


 
Чава   (2004-10-09 14:57) [18]

Белые точки на повернутом битмапе [D7, WinXP]

dimon_prorammer   (07.04.04 12:54)  
Почему если вертеть битмап по формулам:
x1=x0+(x-x0)cos(a)-(y-y0)sin(a)
y1=y0+(x-x0)sin(a)+(y-0)cos(a),
где a-угол, x1,y1-новые координаты, то в результате на картинке
будут белые точки? Как от них избавится?
--------------------------------------------------------------------------------
MBo ©   (07.04.04 13:28) [1]
Нужно делать обратный маппинг, т.е. каждой точке нового битмапа ставить в соответствие точку старого.
--------------------------------------------------------------------------------
miek ©   (07.04.04 18:16) [2]
Или (что проще, но очень некрасиво) каждую точку выводить два раза - туда, куда надо и в соседнюю позицию справа.
--------------------------------------------------------------------------------
MBo ©   (07.04.04 18:18) [3]
это ничем не проще (за исключением отслеживания границ)
--------------------------------------------------------------------------------
bolegator ©   (21.04.04 13:11) [4]
Простой поворот хорош только для картинок, начиная
с разрешения 500 dpi и выше. В остальных случаях
поворот будет искажать картинку. Выхода два:
1) использовать поворот с интерполяцией (линейной или нелинейной),
2) использовать антиалиасинг-поворот.
Первый способ хорош для цветных изображений и плох для черно-белых. Второй способ хорош для черно-белых.
Ну и MBo конечно прав. Хотя я думаю, что точки от этого не пропадут, но скорость поворота увеличится.
--------------------------------------------------------------------------------
Думкин ©   (21.04.04 13:42) [5]
> bolegator ©   (21.04.04 13:11) [4]
> Ну и MBo конечно прав. Хотя я думаю, что точки от этого не пропадут, но скорость поворота увеличится.

Они как раз пропадут.


 
Defunct ©   (2004-10-09 15:27) [19]

LicProd

Ты когда-нибудь работал с LCD монитором? Тут тоже самое, хочешь качественного поворота, увеличь изображение раз в 10, поверни со сглаживанием, а потом уменьши.



Страницы: 1 вся ветка

Текущий архив: 2004.10.24;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.049 c
1-1097330321
CoolMan
2004-10-09 17:58
2004.10.24
Скрытый поиск по маске с копированием


8-1090870151
Pa5ha
2004-07-26 23:29
2004.10.24
array of array of real;


1-1097138190
Akoli
2004-10-07 12:36
2004.10.24
как написать на делфях COPY FILE1 + FILE2 FILE3


1-1097249438
greenrul
2004-10-08 19:30
2004.10.24
ActionToolbar и ActionMainMenu - иконки разных размеров


14-1097041840
9k33
2004-10-06 09:50
2004.10.24
Кодерам и заказчикам