Люди, подскажите пожалуйста. Мне необходимо сделать панораму. Длинная кортинка, которая едет по форме. Но когда я двигаю компонент Image по форме image.left:=image.left+1 картинка как будто мерцает и на какоето время пропадает. Мне сказали что так сделать не получится. А как же тогда мне сделать панораму? Заранее спасибо! Alx
Проще всего было бы через DX... С простым TImage это не думаю, что пройдёт...
:p2: А тогда, соответственно, вопрос. В двух словах - что такое DX? Это какойто компонент?
В общем случае - нет DX - Это уж совсем кратко от DirectX Хотя и компоненты такие есть...
DX - это видимо DirectX, компонент, ага... только не дельфы, а винды...
но и без него можно сделать кое-что:
var Bmp: TBitmap;
...
Form1.Canvas.CopyRect(Form1.ClientRect,
Bmp.Canvas, Rect(offset, 0, Form1.ClientWidth+offset, Form1.ClientHeight));
...
// ClientRect=(0,0,ClientWidth,ClientHeight) - внутреннее пространство формы
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Timer1Timer(Sender: TObject);
end;
var
Form1: TForm1;
Bitmap: TBitmap;
x: integer;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
doublebuffered:=true;
Bitmap := TBitmap.Create;
Bitmap.LoadFromFile('EARTH2.bmp');
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
Canvas.CopyRect(clientrect,Bitmap.Canvas,rect(x,0,x+clientwidth,clientheight));
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Bitmap.Free;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
inc(x);
if x+clientwidth>=1024 then x:=0;
repaint;
end;
end.
Вау какой код. ОГРОМНЫЙ РЕСПЕКТ и человеческое СПАСИБО. Вечером попробую включить.
Да, вот про DoubleBuffered я и не подумал А под DX есть и дельфийские компоненты, с которыми всё довольно легко получается. Там инкапсулирована вся работа с интерфейсами, так что пишешь как под GDI через Canvas
Так этот код не будет работать? Я даже не знаю что такое DoubleBuffered... Ладно, лезу в интернет искать ДиректХ.
DoubleBuffered, это когда форма поддерживает что-то типа того, что в DOS'е называелось видеостраницами. Т. е. когда есть возможность рисования "в какой-то кусок памяти", который в последствии подставляется на место видеопамяти. Т. к. такой вариант заметно превосходит по скорости все другие, то мерцание исчезает. В DX есть такие BackBuffers, которые именно это и представляют.
Дааа. Нашел я какие-то тексты по изучению DirectX (DelphiX).... Это не для меня. Я пока не настолько крут в программировании. BlackShadow, а почему не будет работать тот код который ты тут написал??? Неужели на Делфи так трудно сдвинуть картинку с места (без мирцания)?
Я тут код написал???
Тот код, что присла P@sh@ вполне может и отработать. Очень даже может. Я же этого и не отрицал... Попробуй. DX просто круче Посмотрю дома модули. У меня вроде было что-то по-круче чем DelphiX, который только интерфейсы и описывает...
DoubleBuffered просто включает режим, когда Canvas формы становится как бы невидимым, дублируется в памяти, и все рисование делается на нём, а на экран выводится уже готовая картинка, мерцания нет, потому что на экране ничего не ПЕРЕрисовывается...
PS: этот режим памяти больше требует...
DirectX штука несложная, если не лезть в Direct3D, а ограничиться только прямым доступом к видеопамяти... само собой, это будет намного быстрее GDI
Люди, а вот посмотрите. В том коде, который написал P@sh@ я объединил 2 процедуры.
Это не из-зп версии Delphi. Я бы посоветывал тебе добавить ещё и InvalidateRect после изменения положения картинки.
А вот если я в коде убираю repaint, то тогда мирцание изчезает. Но тогда за рисунком остается размазаный след от него. Но этот след тогда у меня будет оставаться под картинкой и за пределами формы. Этот след не занимает много памяти. Это не картинка на картинке на картинке?
А вот InvalidateRect; - это селая строчка? Там никакие парамерры не нужны?
procedure TForm1.Timer1Timer(Sender: TObject);
begin
x:=x-1;
repaint;
Canvas.CopyRect(clientrect,Bitmap.Canvas,rect(x,0,x+clientwidth,clientheight));
end;
Но так как написал P@sh@ у меня не как не выходит. Я не понимаю что вызывает процедуру
Ну а почему у меня процедура не вызывается?:
BlackShadow
"Свернутое окно не рисует на своей канве". И то верно! :D Надо точнее излагать свои мысли. Я хотел сказать, что если его потом развернуть обратно...
to AIx
Ладно уж, берите, только не говорите, что оно опять не работает... Меньшего мерцания Вы едва ли добьетесь средствами GDI.
Прикрепленные файлы
Panorama.zip ( 199.07 килобайт )
Кол-во скачиваний: 264
Бродяжник, надеюсь к критике ты относишься нормально :p2:
Вот это сильно по глазам ударило:
Timer1.Enabled:=false;
x:=0;
Спасибо! Вечером, как только доберусь до Делфи, буду пробовать.
Нормально отношусь! Ламер я... зато со стажем! Таймер я в программе отключил, чтобы наглядно было видно, что при старте программы он должен быть отключен. Когда его на форму кидаешь, он по умолчанию включен. Конечно, его нужно отключать прямо в Инспекторе объектов. А про инициализированные переменные в Дельфи я и правда не знал... я всю жизнь думал, что это привилегия Си. И с InvalidateRect vs Repaint тоже справедливо. А мерцать все равно будет на больших картинках, другое дело, что без двойной буфферизации мерцать будет гораздо мерцательнее.
В зависимости от версии переменные могут быть инициализированы или так Const x:Integer=0; или так Var x:Integer=0;
Первый вариант ещё и в паскале прокатывает. А ещё так можно статические переменные в функциях объявлять... Но это уже к теме не относится...
А про InvalidateRect vs Repaint ещё как справедливо. Насколько я помню так или иначе Repaint сводится к InvalidateRect(Handle,ClientRect). Незачем в таком случае перерисовывать всё...
а ещё мысль извратная появилась: сделать 2 TImage, расположить их друг на друге и делать так:
1). Рисуем в "спрятанном"
2). Выносим его вперёд.
Дальше вроде понятно. Что-то типа "видеостраницы своими руками". Вот в душе не знаю что это даст. Но попробывать можно... Жаль что Delphi под рукой нет
Version 1.1.
Прикрепленные файлы
PANORAMB.ZIP ( 11.39 килобайт )
Кол-во скачиваний: 218
Alx
Ну а почему у меня процедура не вызывается?
Этот метод вызывается автоматически...
а что не рисует... может картинка не подгрузилась?
я же рабочий пример кинул...
PS: картинка у меня была большая (1024х768) и ничего не мерцало абсолютно
Ой! Всё супер! Не мерцает! СПАСИБОЧКИ!
Вот только если вы тут такие умные собрались, может скажите, пожалуйста, можно так картинку не БМП, а ЙПГ крутить????? И если да, то как?
А что jpg нельзя загрузить так же как и bmp? Тогда попроьуй TPaintBox что ли... Позабывал уже всё с этим .Net
Alx
насчет bmp и jpeg - я использовал класс TBitmap для загрузки картинки... есть и другие - TJPEGImage, например...
но лучше использовать универсальный TPicture - он сам распознает картинку по расширению файла, а рисовать можно через его свойство Graphic: что-то типа form1.canvas.draw(...., picture1.graphic);