Как ускорить прорисовку векторной графики ?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: Как ускорить прорисовку векторной графики ?

Сообщение Alex2013 » 14.11.2016 01:34:12

zub писал(а):>>И что эмулировать на уровне канваса никак нельзя ? :roll: (Там же просто запись команд в формате WMF вместо реального рисования )
Тебе и карты в руки))
http://msdn.microsoft.com/en-us/library/cc250370.aspx
http://wvware.sourceforge.net/caolan/ora-wmf.html
http://www.symantec.com/avcenter/refere ... format.pdf

Мне в ближайшей перспективе пока не нужно ... о кто знает что дальше будет ... :idea:
Хотя я читал, что вроде уже есть готовая библиотека :arrow: http://wiki.lazarus.freepascal.org/fpvectorial
+ где-то что-то упрятано в TAChart.... (запись в WMF)
>>(Да и близко довольно к теме : мерцание нужно победить по возможности не теряя скорости )
Дак оно прекрасно побеждается без потерь производительности. Такими кусками кода ты общаешся сам с собой. Есть проблема - делаешь минимальную демку ее демонстрирующую

Мысль верная... но уж больно лениво . :oops: ... в прочем некоторые вещи действительно удобнее демкой показать ( больше шансов что кто-то повозится захочет ...)
Alex2013
долгожитель
 
Сообщения: 2937
Зарегистрирован: 03.04.2013 11:59:44

Re: Как ускорить прорисовку векторной графики ?

Сообщение zub » 14.11.2016 02:19:42

>>Хотя я читал, что вроде уже есть готовая библиотека :arrow: http://wiki.lazarus.freepascal.org/fpvectorial
С такимже успехом можно сказать что у тебя есть готовый векторный редактор. Забудь про вмф в линуксе.
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Как ускорить прорисовку векторной графики ?

Сообщение Alex2013 » 14.11.2016 02:50:43

zub писал(а):>>Хотя я читал, что вроде уже есть готовая библиотека :arrow: http://wiki.lazarus.freepascal.org/fpvectorial
С такимже успехом можно сказать что у тебя есть готовый векторный редактор. Забудь про вмф в линуксе.

Почти убедил ... :wink:
Alex2013
долгожитель
 
Сообщения: 2937
Зарегистрирован: 03.04.2013 11:59:44

Re: Как ускорить прорисовку векторной графики ?

Сообщение alexey38 » 14.11.2016 12:03:08

Alex2013 писал(а):Тормозов вроде не наблюдается


У нас основной способ был - это просто очистить битмап, и вывести в него метафайл штатными средствами. Это как раз работает довольно таки быстро, при разумном числе элементов.

Манипуляции с битмапом осуществлялись только в процессе рисования, когда мышкой тянем рамку, линию или иной элемент. Опять же не нужно бояться тупо делать вывод фоновой копии готового битмапа, все это работает быстро, т.к. объем битмапа ограничивается всего навсего мегабайтами. При наличии видеоускорителей эти операции ускорятся за счет реализации драйверов. То есть суть ускорения в том, чтобы внутри программы ничего не делать, а отдавать на откуп GDI вывод метафайла в битмап, и битмапа на форму, тогда аппаратное ускорение железа как раз и будет задействовано.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Как ускорить прорисовку векторной графики ?

Сообщение Linus » 15.11.2016 00:54:05

Дублирую сообщение
Имеется массив (некоторая область памяти), содержащая грубо говоря битовую матрицу. Как загрузить это / отобразить минуя
Код: Выделить всё
FileWrite (F, bmp[0], sizeof(...); ...LoadFromFile(....);\0


или банальная переформулировка вопроса:
Как сказать (компоненту) что вот здесь лежит изображение, возьми и загрузи его.
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Re: Как ускорить прорисовку векторной графики ?

Сообщение zub » 15.11.2016 01:45:58

Linus
TBitmap наследует от TRasterImage много вариантов LoadОткудаНибудь
в частности
Код: Выделить всё
    procedure LoadFromBitmapHandles(ABitmap, AMask: HBitmap; ARect: PRect = nil);
    procedure LoadFromDevice(DC: HDC); virtual;
    procedure LoadFromStream(AStream: TStream); overload; override;
    procedure LoadFromStream(AStream: TStream; ASize: Cardinal); overload; virtual;
    procedure LoadFromMimeStream(AStream: TStream; const AMimeType: string); override;
    procedure LoadFromRawImage(const AIMage: TRawImage; ADataOwner: Boolean);
    procedure LoadFromIntfImage(IntfImage: TLazIntfImage);

Возможно подойдет LoadFromStream или LoadFromRawImage. В первом случае "массив (некоторая область памяти)" должен быть в потоке, во втором надо создать TRawImage над "массив (некоторая область памяти)" естественно всё должно быть в понятных лцлю форматах, а не как вам на душу придет.
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Как ускорить прорисовку векторной графики ?

Сообщение Linus » 15.11.2016 02:05:02

zub писал(а):Linus
TBitmap наследует от TRasterImage много вариантов LoadОткудаНибудь
в частности
Код: Выделить всё
    procedure LoadFromBitmapHandles(ABitmap, AMask: HBitmap; ARect: PRect = nil);
    procedure LoadFromDevice(DC: HDC); virtual;
    procedure LoadFromStream(AStream: TStream); overload; override;
    procedure LoadFromStream(AStream: TStream; ASize: Cardinal); overload; virtual;
    procedure LoadFromMimeStream(AStream: TStream; const AMimeType: string); override;
    procedure LoadFromRawImage(const AIMage: TRawImage; ADataOwner: Boolean);
    procedure LoadFromIntfImage(IntfImage: TLazIntfImage);

Возможно подойдет LoadFromStream или LoadFromRawImage. В первом случае "массив (некоторая область памяти)" должен быть в потоке, во втором надо создать TRawImage над "массив (некоторая область памяти)" естественно всё должно быть в понятных лцлю форматах, а не как вам на душу придет.


Я вот тоже склонялся к таким вариантам.. но наводит сомнения фраза в задании. "Массив есть файл" и надо "Указать ему адрес откуда взять и все...". Как вы поняли задачка в устной форме, не конкретная, что называется сломай голову.
Вот подумываю не создать ли какой либо класс хотя бы от TPicture, добавив функцию загрузки из TByteArray;
Последний раз редактировалось Linus 15.11.2016 02:14:39, всего редактировалось 1 раз.
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Re: Как ускорить прорисовку векторной графики ?

Сообщение zub » 15.11.2016 02:13:58

Задача сводится к преобразованию того что есть - "Массив есть файл" в того что может быть понято LCLем - нужна конкретика
Насколько я понимаю внутренний формат TRawImage можно довольно гибко настроить, возможно получится обойтись и без преобразований

Добавлено спустя 2 минуты 5 секунд:
>> Как вы поняли задачка в устной форме, не конкретная, что называется сломай голову.
>> Вот подумываю не создать ли какой либо
В усной форме можно подумывать о чем угодно. Впринципе можно даже сказать что задача решена))

Добавлено спустя 3 минуты 18 секунд:
>>класс хотя бы от TPicture, добавив функцию загрузки из TByteArray;
я ничего не пробовал, но глядя на TRawImageDescription думаю что получится грузить почти любой простой формат
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Как ускорить прорисовку векторной графики ?

Сообщение Linus » 15.11.2016 02:42:41

zub писал(а):Задача сводится к преобразованию того что есть - "Массив есть файл" в того что может быть понято LCLем - нужна конкретика
Насколько я понимаю внутренний формат TRawImage можно довольно гибко настроить, возможно получится обойтись и без преобразований


TRawImage вроде то что нужно, однако как в него загрузить готовенькое не особо ясно. Примеров в сети не очень много.

Код: Выделить всё
RI.Init;
  RI.Data:=@bmp[0];
  RI.DataSize:=size;
  RI.Mask:=nil;
  RI.DataSize:=0;
  RI.Palette:=nil;
  RI.PaletteSize:=0;

im.Picture.Bitmap.LoadFromRawImage(RI, true/false);


Вроде и не шлет на ** и результата нет..
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Re: Как ускорить прорисовку векторной графики ?

Сообщение zub » 15.11.2016 02:47:21

надо настроить RI.Description в соответствии с форматом?
RI.DataSize:=0;??

Добавлено спустя 3 минуты 8 секунд:
давай демку
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Как ускорить прорисовку векторной графики ?

Сообщение Linus » 15.11.2016 02:55:32

zub писал(а):надо настроить RI.Description в соответствии с форматом?
RI.DataSize:=0;??

Добавлено спустя 3 минуты 8 секунд:
давай демку


Я думал обойдется без этого. Снова расщеплять на хеадер и дату) хотя.. хедер = биты 0 до 25 дата = 26..и далее
RI.DataSize:=0; да не заметил, должен был быть MaskSize)

Добавлено спустя 18 минут 24 секунды:
Спасибо Zub через TRaw действительно удобно
Код: Выделить всё
RIHeader.Init;
  RIHeader.Init_BPP24_B8G8R8_BIO_TTB(w,h);

  RI.Init;
  RI.Description:= RIHeader;
  RI.Data:=@bmp[26];
  RI.DataSize:=size-26;

  im.Picture.Bitmap.LoadFromRawImage(RI, false);  \0


Однако просьба была хедеры генерировать вручную а тут TRawImageDescription....
<думаю как завязать его на содержимом массива>
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Re: Как ускорить прорисовку векторной графики ?

Сообщение zub » 15.11.2016 03:17:51

RI.Init;
RI.Description.Init_BPP24_B8G8R8_BIO_TTB(w,h);
RI.Data:=@bmp[26];
RI.DataSize:=size-26;

im.Picture.Bitmap.LoadFromRawImage(RI, false); \0
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Как ускорить прорисовку векторной графики ?

Сообщение Linus » 15.11.2016 03:22:23

zub писал(а):RI.Init;
RI.Description.Init_BPP24_B8G8R8_BIO_TTB(w,h);
RI.Data:=@bmp[26];
RI.DataSize:=size-26;

im.Picture.Bitmap.LoadFromRawImage(RI, false);


по сути то же самое)

Вот. Думаю такой ответ устроит.
Код: Выделить всё
var
  bmp:TByteArray; 
  size:Dword;
  w,h:word;
  RI:TRawImage;
Begin
....
CreadeBMPHeader(bmp, w,h, size);  //скрыл в процедуру создание заголовка файла
...
//делаем с пикселями что хотим
...
//сохраняем на диск (для отладки)
...
FileWrite (F, bmp[0], size);
FileClose (F);

//выводим
RI.Init;
  with RI.Description do
  begin
        Init;
        format:=ricfRGBA;
        Depth:=bmp[24];
        BitsPerPixel:=Depth;

        Width:=bmp[18];
        Height:=bmp[20];

        RedPrec  :=(Depth div 3);
        GreenPrec:=RedPrec;
        BluePrec :=RedPrec;

        RedShift:=RedPrec*2;
        GreenShift:=GreenPrec;
        BlueShift:=0;
  end;

  RI.Data:=@bmp[bmp[10]];
  RI.DataSize:=size-bmp[10];

  im.Picture.Bitmap.LoadFromRawImage(RI, false);
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Re: Как ускорить прорисовку векторной графики ?

Сообщение zub » 15.11.2016 03:45:03

вместо Init_BPP24_B8G8R8_BIO_TTB ручная настройка на основе bmp[0]..bmp[26] = десяток строк.
кстати, наверно можно сразу юзать
Код: Выделить всё
TBitmap
property RawImage: TRawImage read GetRawImage; // be carefull with this, modify only within a begin/endupdate

Но это никакой не прямой доступ в видеопамять, как предполагалось в первоначальной постановке
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Как ускорить прорисовку векторной графики ?

Сообщение Alex2013 » 15.11.2016 23:15:39

А почему так нельзя ?
Код: Выделить всё
Procedure SaveRAW(FN:String;B:TBitmap);
var
   F:TFileStream;
begin
F:=TFileStream.Create(FN,fmCreate );
F.Write(b.RawImage.Data^,b.RawImage.DataSize);
F.Free;
end;

Проще ведь ! :idea:
Если размер картинки и прочие параметры не меняются то ИМХО проще не придумаешь .
Alex2013
долгожитель
 
Сообщения: 2937
Зарегистрирован: 03.04.2013 11:59:44

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12

Рейтинг@Mail.ru