Текущий архив: 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.54 MB
Время: 0.006 c