Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi: Графика, звук, видео
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/10: Рейтинг темы: голосов - 10, средняя оценка - 4.80
snake32
1864 / 1176 / 205
Регистрация: 26.02.2009
Сообщений: 4,505
Записей в блоге: 5
1

Ожидание окончания отрисовки Canvas / очистка драйвера

26.02.2013, 21:01. Просмотров 2065. Ответов 11
Метки нет (Все метки)

Доброго времени!

Есть код следующего вида
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
bmp := TBitmap.Create;
bmp.SetSize( 256, 256 );
 
for i:=loy to hiy do// очень много итераций
  for j:=lox to hix do// очень много итераций
  begin
    //здесь очищаю bmp через FillRect
    // далее рисую необходимые мне объекты в bmp на каждой итерации они разные
    // потом сохраняю bmp в стрим 
  end;
 
bmp.Free;
После этого в стриме при больших кол-вах итераций циклов появляется одинаковые bmp - хотя они должны быть все разные! То есть в стрим кладется только Энная копия до конца выпонения кода. И эта не моя ошибка! Так как если создание и уничтожение bmp поместить внутырь циклов ТО всё ОК, копий нет.

Есть мысли по поводу драйвера, мол тот накапливает команды и когда их большое кол-во то его заклинивает и больше он уже ни чего не рисует, а кладёт только то что последнее удалось нарисовать.
Как обнулить поток команд? Или как дождаться пока он сам это сделает?
Пробовал Canvas.Refresh, Lock-Unlock. Ничего не помогает! Кто-нить сталкивался с таким чудом?
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.02.2013, 21:01
Ответы с готовыми решениями:

Очистка Canvas объекта TImage
Здравствуйте! Знаю, вопрос очень популярный и на него неоднократно давались ответы на самых разных...

Задержка отрисовки Canvas. MotionEvent
Здравствуйте. Написал простейшую программу рисующую жёлтую точку при касании экрана. Как только...

Ожидание окончания процедуры
Имеется процедура поиска изображения и клик по нему procedure Search(name:string) и имеется...

Ожидание окончания exec
Здравствуйте! Пишу так exec('mysql -uNAME -pPASSWORD DATABASE < base.sql'); ...

Ожидание окончания работы Timer
Итак проблема вот в чём: у меня в программе вылетают шарики из разных труб(случайных), вылет шара...

11
mss
2641 / 2265 / 277
Регистрация: 24.12.2010
Сообщений: 13,725
26.02.2013, 21:23 2
Цитата Сообщение от snake32 Посмотреть сообщение
эта не моя ошибка
Конечно не твоя.
Как всегда глючная винда и кривая делфи виновата.
А у тебя всё пучком.
0
cotseec
Пишу на Delphi...иногда
1416 / 1274 / 285
Регистрация: 03.12.2012
Сообщений: 3,914
Записей в блоге: 5
Завершенные тесты: 3
26.02.2013, 21:27 3
Цитата Сообщение от snake32 Посмотреть сообщение
Так как если создание и уничтожение bmp поместить внутырь циклов ТО всё ОК, копий нет.
а почему и не поместить?
по приведенному коду видно, что битмап создается в одном экземпляре и вся работа проводится с ним, а вот как организована укладка в поток - не известно, может где-то недоочищаете нарисованные объекты?
0
snake32
1864 / 1176 / 205
Регистрация: 26.02.2009
Сообщений: 4,505
Записей в блоге: 5
26.02.2013, 22:46  [ТС] 4
Цитата Сообщение от cotseec Посмотреть сообщение
а почему и не поместить?
А зачем? Я старюсь миллион раз не создавать/уничтожать объекты без причины.
Цитата Сообщение от cotseec Посмотреть сообщение
по приведенному коду видно, что битмап создается в одном экземпляре и вся работа проводится с ним, а вот как организована укладка в поток - не известно, может где-то недоочищаете нарисованные объекты?
Ну да, первые 1000-5000 итераций очищаю, а потом резко вообще перестаю рисовать...

mss, конечно пучком! Сомневаетесь? Могу полный код показать метода... но почему то я уверен что дело не в нём ибо простое перемещение внутрь цикла не помогло бы.
0
mss
2641 / 2265 / 277
Регистрация: 24.12.2010
Сообщений: 13,725
26.02.2013, 23:06 5
Цитата Сообщение от snake32 Посмотреть сообщение
Могу полный код показать
Зачем ? Ты же не сомневаешься в нем - значит это глюкавая винда и делфи виноваты.
0
snake32
1864 / 1176 / 205
Регистрация: 26.02.2009
Сообщений: 4,505
Записей в блоге: 5
27.02.2013, 00:59  [ТС] 6
Цитата Сообщение от mss Посмотреть сообщение
Зачем ?
держи:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
procedure TBLMPart.SaveToFile( part:TPart; var startpos:int64; vpi:TViewProgressItem=nil );
  const BufSize = 500*1024*1024;
        limitBuf = BufSize - ( 256*256*3+200 );
  var mc:TMercator;
      x,y,i,k:integer;
      bmp:TBitMap;
      tilepath:string;
      tileindex:TRect;
      pic:TPicture;
      tileIsEmpty, waserr:Boolean;
      bufDWORD: array of DWORD;
      lastsize, posImageArray, posTableoffs:Int64;
      MemBuf,IndexBuf:TMemoryStream;
begin
  waserr := true;
  FPStart := startpos;
  mc.Init( TMercatorType(part.Zoom.Desc.ProjType), part.Zoom.Zoom+1 );
  tileindex := mc.GetTilesIndex( part.Bound );
 
  FHeader.Make( part );
 
  bmp := nil; pic := nil; FreeAndNIL(FPictFormat);
  MemBuf := nil; IndexBuf := nil;
 
  vpi.Start( vpi, FHeader.countHeight*FHeader.countWidth,
              'Масштаб : z'+IntToStr(FHeader.zoom)+' Часть : '+part.Name );
  try
    pic := TPicture.Create;
    FPictFormat := FHeader.GetFormatClass.Create;
    SetLength( bufDWORD, FHeader.countWidth );
    MemBuf := TMemoryStream.Create;
    MemBuf.SetSize( BufSize );
 
    IndexBuf := TMemoryStream.Create;
    IndexBuf.SetSize(FHeader.countHeight * FHeader.countWidth * sizeof(DWORD));
    IndexBuf.Position := 0;
 
 
 
    posTableoffs := FPStart + sizeof( FHeader );
    posImageArray := posTableoffs + IndexBuf.Size;
 
    FBLMObj.FFile.Position := posImageArray;
    for y:=tileindex.Top to tileindex.Bottom do
    begin
      for x:=tileindex.Left to tileindex.Right do
      begin
        i := x - tileindex.Left;
        tileIsEmpty := true;
        bufDWORD[i] := 0;
 
        bmp := nil;
        bmp := TBitMap.Create;
        try
          bmp.SetSize( 256, 256 );
          bmp.PixelFormat := pf24bit;
          bmp.Canvas.Lock;
          try
 
            bmp.Canvas.Brush.Color := clWhite;
            bmp.Canvas.Brush.Style := bsSolid;
            bmp.Canvas.FillRect( Rect( 0, 0, bmp.Width, bmp.Height ) );
            bmp.Canvas.Refresh;
          finally
            bmp.Canvas.Unlock;
          end;
          for k:=0 to Part.Layers.Count-1 do
          begin
            tilepath := part.GetTilePath( k, x, y );
            if not FileExists( tilepath ) then
              continue;
            try
              pic.LoadFromFile( tilepath );
              bmp.Canvas.Lock;
              try
                bmp.Canvas.Draw( 0,0, pic.Graphic );
                bmp.Canvas.Refresh;
              finally
                bmp.Canvas.Unlock;
              end;
              tileIsEmpty := false;
            except
            end;
          end;
 
          if vpi.Progress( vpi, 1 ) then
            exit;
 
          if not tileIsEmpty then
            FPictFormat.Assign( bmp );
        finally
          FreeAndNIL( bmp );
        end;
 
        if tileIsEmpty then
          continue;
 
        lastsize := MemBuf.Position;
        FPictFormat.SaveToStream( MemBuf );
        bufDWORD[i] := MemBuf.Position - lastsize;
 
        if( MemBuf.Size - MemBuf.Position ) < limitBuf then
        begin
          FBLMObj.FFile.WriteBuffer( Pointer(MemBuf.Memory)^, MemBuf.Position );
          MemBuf.Position := 0;
        end;
 
      end;
      IndexBuf.WriteBuffer( Pointer(bufDWORD)^, Length(bufDWORD)*sizeof(DWORD) );
    end;
 
    if MemBuf.Position > 0 then
      FBLMObj.FFile.WriteBuffer( Pointer(MemBuf.Memory)^, MemBuf.Position );
    startpos := FBLMObj.FFile.Position;
 
    FHeader.size := FBLMObj.FFile.Position - FPStart;
    FBLMObj.FFile.Position := FPStart;
    FBLMObj.FFile.WriteBuffer( FHeader, sizeof( FHeader ) );
 
    FBLMObj.FFile.Position := posTableoffs;
    FBLMObj.FFile.WriteBuffer( Pointer(IndexBuf.Memory)^, IndexBuf.Size );
    waserr := false;
  finally
    FreeAndNIL( pic );
    FreeAndNIL( FPictFormat );
    FreeAndNIL( MemBuf );
    FreeAndNIL( IndexBuf );
    if waserr then startpos := FPStart
              else Inc( FBLMObj.FHeader.layerCount );
    vpi.Finish( vpi );
  end;
end;
Добавлено через 59 секунд
Это рабочий код, но тут внутри цикла создается bmp
0
mss
2641 / 2265 / 277
Регистрация: 24.12.2010
Сообщений: 13,725
27.02.2013, 09:21 7
И кто такой FPictFormat ?
0
snake32
1864 / 1176 / 205
Регистрация: 26.02.2009
Сообщений: 4,505
Записей в блоге: 5
27.02.2013, 09:51  [ТС] 8
Цитата Сообщение от mss Посмотреть сообщение
И кто такой FPictFormat ?
Это TGraphic. В зависимости от формата может быть TPNGImage, TJPEGImage либо TBitmap
0
mss
2641 / 2265 / 277
Регистрация: 24.12.2010
Сообщений: 13,725
27.02.2013, 10:37 9
Не вижу нужды в теле цикла делать с битмапом что-либо кроме Canvas.Fill и Canvas.Draw
0
snake32
1864 / 1176 / 205
Регистрация: 26.02.2009
Сообщений: 4,505
Записей в блоге: 5
27.02.2013, 11:45  [ТС] 10
Цитата Сообщение от mss Посмотреть сообщение
Не вижу нужды в теле цикла делать с битмапом что-либо кроме Canvas.Fill и Canvas.Draw
Остальное осталось от экспериментов когда создание/уничтожение bmp было вне цикла.

Добавлено через 1 минуту
Fill кстати тоже можно убрать так как по дефолту bmp - белый. как мне и нужно
0
mss
2641 / 2265 / 277
Регистрация: 24.12.2010
Сообщений: 13,725
27.02.2013, 11:49 11
Убирай все эксперименты, филл и прочую несущественную лабуду с потоками, копированиями-назначениями и пр.
Оставь только FPictFormat.Assign(bmp) и FPictFormat.SaveToFile() - только тогда будет "чистый эксперимент".
0
snake32
1864 / 1176 / 205
Регистрация: 26.02.2009
Сообщений: 4,505
Записей в блоге: 5
27.02.2013, 13:45  [ТС] 12
Хорошо, может быть позже выделю время и сделаю проект который покажет этот баг
0
27.02.2013, 13:45
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.02.2013, 13:45

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

OnDocumentComplete или ожидание окончания загрузки
Страница загружается при событие OnCreate. procedure TfrmMain.FormCreate(Sender: TObject);...

Динамическое создание потоков, и ожидание их окончания
И так! У меня такая проблема возникла. Хочется чтобы программа работала в многопоточном режиме. ...

Ожидание окончания работы запущенных процессов
Запуск N заданных пользователем процессов. Ожидание окончания работы запущенных процессов. *на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.