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

Вниз

Аналоговые часы   Найти похожие ветки 

 
исследователь ©   (2007-08-18 18:14) [0]

Такой вопрос: пишу программку-прото аналоговые часики, для души, с поддержкой скинов. Есть красивые картинки скинов, но фон циферблата в них градиентный. Отсюда вопрос: как закрашивать стрелку по событию таймера так, чтобы не было ее видно, ведь ее нужно будет отрисовывать в другом месте.


 
Ricks ©   (2007-08-18 18:18) [1]

рисуй во временный битмап сначала фон, потом в нужном месте стрелку, а потом выводи


 
исследователь ©   (2007-08-18 18:21) [2]

CopyRect и BrushCopy?


 
Ricks ©   (2007-08-18 18:26) [3]

можно CopyRect, но вообще лучше BitBlt - немного быстрее
BrushCopy, извини, не знаю что делает. я, вообще, все что связанно с Canvas <=> HDC делаю на API


 
исследователь ©   (2007-08-18 18:30) [4]

Алгоритм работы с вызовами функций можешь накидать примерно?


 
@!!ex ©   (2007-08-18 19:07) [5]

BitBlt(DestinationHandle, X,Y,Width,Height, SourceHandle, X,Y, SRCCOPY);
Handle = Canvas.Handle


 
исследователь ©   (2007-08-18 19:08) [6]

Замечательый просто "алгоритм" :)

Перефразирую: как скопировать часть формы в TBitmap?


 
@!!ex ©   (2007-08-18 19:15) [7]

Нахрена тебе копировать часть формы на битмап??
Головой думай.
Загружаешь свою картинку в BitMap1.
Создаешь еще один BitMap. BitMap2.
Такого же размера как и битмап1.
Каждый кадр делаешь

BitBlt(BitMap2.Canvas.Handle, X,Y,Width,Height, BitMap1.Canvas.Handle, X,Y, SRCCOPY);
<Тут римуешь на втором битмапе стрелку>
BitBlt(Form1.Canvas.Handle, X,Y,Width,Height, BitMap2.Canvas.Handle, X,Y, SRCCOPY);

Ферштейн?


 
исследователь ©   (2007-08-18 19:20) [8]

Натюрлих :)
Вопросы:
0. Много ли памяти будет жрать?
1. ВАЖНО: что есть X и Y?
ведь у меня стрелка описывается так:

MoveTo(центр_циферблата);
LineTo(CX+Round(HArrow * sin(HA)), CY-Round(HArrow * cos(HA)));

где

Harrow - длина часовой стрелки, HA - угол поворота.

2. Тоже ВАЖНО: что есть Width и Height? Свойства Bitmap1?


 
Ricks ©   (2007-08-18 19:27) [9]

Попытаюсь тебе объяснить. допустим тебе надо нарисовать прямоугольную область, верхний левый угол которой будет находиться в координатах (100; 150), и размером она будет 200 на 250 точек. Так вот X=100 Y=150, Width=200, Height=250. Усёк?

В свойствах TBitmap есть Width и Height, а рисовать ты его будешь начиная с (X; Y)


 
исследователь ©   (2007-08-18 19:37) [10]

Это-то понятно, а вот со стрелкой - не очень. Вот я гружу в Bitmap1 изображение циферблата, так?

Далее делаю Bitmap2.width:=bitam1.width; и то же с высотой. Так?

Далее пишу

xx:=bitmap1.width div 2;
yy:=bitmap1.height div 2
BitBlt(Bitmap2.Canvas.Handle,
       xx,yy,
       xx+Round(MArrow * sin(MA)), yy+Round(MArrow * cos(MA)),
       Bitmap1.Canvas.Handle, xx, yy, SRCCOPY);


не пашет


 
исследователь ©   (2007-08-18 19:41) [11]

не обращайте внимания на опечатки


 
Ricks ©   (2007-08-18 19:41) [12]

Стрелку рисуй уже на самом битмапе
Bitmap.Canvas.MoveTo()
Bitmap.Canvas.LineTo();

BitBlt это типа CopyRect - переносит прямоугольное изображение


 
исследователь ©   (2007-08-18 19:44) [13]

Про BitBlt я знаю, что она переносит изображение. А фон где рисовать?


 
исследователь ©   (2007-08-18 19:54) [14]

Все, понял, но осталась пара вопросов.

Выходит, что x и у равны нулю, так как мы копируем полностью циферблат???


 
Ricks ©   (2007-08-18 20:12) [15]

Ну вот смотри и пробуй разобраться:
type
 TForm1 = class(TForm)
   MainTimer: TTimer;
   procedure FormCreate(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
   procedure MainTimerTimer(Sender: TObject);
 private
   { Private declarations }
 public
  aImage : TBitmap;
  aSkin  : TBitmap;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
aImage:=TBitmap.Create;
aSkin:=TBitmap.Create;

aImage.Width:=100;
aImage.Height:=100;

aSkin.Width:=100;
aSkin.Height:=100;

aSkin.LoadFromFile(...)
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
aImage.Free;
aSkin.Free;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var h, m, s, n : word;
   a : single;
begin
BitBlt( aImage.Canvas.Handle,
 0, 0, 100, 100, aSkin.Canvas.Handle, 0, 0, SRCCOPY );

with aImage.Canvas do begin
 MoveTo(50, 50);
 DecodeTime(GetTime, h, m, s, n);
 a:=2*pi * s/60 + pi;
 LineTo( round(50 - sin(a) * 30), round(50 + cos(a) * 30) );
 TextOut(0, 0, IntToStr(s));
end;

BitBlt( Canvas.Handle,
 100, 100, 100, 100, aImage.Canvas.Handle, 0, 0, SRCCOPY );
end;


 
исследователь ©   (2007-08-18 20:14) [16]

Ну в общем, как я и сказал, циферблат копируется полностью. Верно?


 
Ricks ©   (2007-08-18 20:17) [17]

Да.
Сначала копируешь фон (циферблат) полностью во временный битмап, потом на временном рисуешь стрелку. И за этим рисуешь временный на форме.
Удачи


 
исследователь ©   (2007-08-18 20:18) [18]

А вариант копировать только там, где стрелочка прорисовалась? Так и памяти жрать меньше будет


 
antonn ©   (2007-08-18 20:40) [19]

у тебя памяти 16Мб?


 
исследователь ©   (2007-08-18 20:41) [20]

Нет, 2 гига, но все же...


 
Ricks ©   (2007-08-18 20:49) [21]

ты потратишь больше памяти на копирование непрямоугольной картинки...


 
исследователь ©   (2007-08-18 20:59) [22]

Кстати, стала очень заметна рябь при использовании больших картинок.

И еще: как теперь привязать к этому скины... копируем-то мы ПРЯМОУГОЛЬНЫЙ циферблат, а форма будет НЕПРЯМОУГОЛЬНАЯ...


 
исследователь ©   (2007-08-18 20:59) [23]

Кстати, стала очень заметна рябь при использовании больших картинок.

И еще: как теперь привязать к этому скины... копируем-то мы ПРЯМОУГОЛЬНЫЙ циферблат, а форма будет НЕПРЯМОУГОЛЬНАЯ...


 
antonn ©   (2007-08-18 21:20) [24]

копируй прямоугольные, форму вырезай непрямоугольную, в чем загвоздка?


 
исследователь ©   (2007-08-18 21:34) [25]

Да я уж проверил... все норм... а вот с мерцанием -  это отстой.


 
исследователь ©   (2007-08-18 21:38) [26]

А как сделать линии плавными? В инете лишь дурацкий урок какой-то, но он не катит, а при изменении максимума x и у в нем на width и height формы она вообще не видна становится


 
исследователь ©   (2007-08-18 23:32) [27]

Никто не знает?


 
Vendict ©   (2007-08-19 12:34) [28]

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


 
исследователь ©   (2007-08-19 14:46) [29]

Да скин я сделал, а как сглаживание юзать?


 
@!!ex ©   (2007-08-19 17:40) [30]

> Кстати, стала очень заметна рябь при использовании больших
> картинок.

Косяк связанный с тем, что при перерисовке сначала форма заливаеться родным цветом, а потом на нее уже ложиться BitBlt.
Из за этогО, елси например форма синяя, а копируеться белый битмап будет мерцание:
форма при перерисовке заливаеться синим, на нее накладываеться битмап, при перерисовке битмап стирается цветом формы и накладываеться опять.

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


 
antonn ©   (2007-08-19 20:48) [31]

решение против мерцания - либо двойной буфер (кстати bltbtn очень быстро работает, с ним не должно быть мерцания), либо выводит окошко через updatelayeredwindow() - понятия мерцать там вообще нет (как и понятия контрол, хыхыхы).
рисовать гладкие линии - антиалиасинг. Простой метод - создавать битмап, в несколько раз больше "обычного", рисовать на нем все стрелки и фон так же в несколько раз больше, а потом в эти несколько раз уменьшать до размеров "обычного"


 
@!!ex ©   (2007-08-19 20:55) [32]

> [31] antonn ©   (19.08.07 20:48)

Я думаю мерцание из-за того, что форма перерисовываеться сама.
А насчет сглаживания, зачем уменьшать? Сразу рисовать с StretchBlt.


 
antonn ©   (2007-08-19 21:17) [33]

никаких StretchBlt, попиксельно через scanline со смешением цветов, а то науменьшаешь до "квадратиков":)


 
исследователь ©   (2007-08-20 13:37) [34]

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


 
Dib@zol ©   (2007-08-20 14:32) [35]

InvalidateRect(<Компонент на который выводишь>.Handle, nil, FALSE);
Это теоретически позволит избежать мерцания.


 
antonn ©   (2007-08-20 15:39) [36]


> Я нашел попиксельное решение, но даже с засовыванием в отделный
> тред прога просто виснет и все.

значит это не решение


 
исследователь ©   (2007-08-20 16:16) [37]

Может, ты подскажешь?
Я имел ввиду, как ты понял, не свой код, а нашел в инете.


 
clickmaker ©   (2007-08-20 16:23) [38]


> исследователь ©   (18.08.07 18:14)

а стрелка - это что? Bitmap или линиями?
вариант с SetROP2 инверсным не подойдет?


 
исследователь ©   (2007-08-20 17:27) [39]

Стрелка линией рисуется, выше я это писал.


 
clickmaker ©   (2007-08-20 17:37) [40]


> Стрелка линией рисуется

SetROP2(Canvas.Handle, R2_NOTXORPEN);

рисуем
секунда прошла
рисуем в том же месте, тем самым стираем
рисуем в другом месте



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

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

Наверх




Память: 0.56 MB
Время: 0.015 c
2-1224561005
Mery
2008-10-21 07:50
2008.11.30
Маска ввода


11-1195858230
Jon
2007-11-24 01:50
2008.11.30
Menu messages


2-1224490297
Mozgan
2008-10-20 12:11
2008.11.30
Перенос компонента из delphi 6 в delphi 7


2-1224182146
MZG
2008-10-16 22:35
2008.11.30
Не запускается прога с БД, что не так?


2-1224101270
I_g_o_r
2008-10-16 00:07
2008.11.30
Ошибка при выполнении запроса