Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
16 / 16 / 1
Регистрация: 29.11.2014
Сообщений: 227

GDI+. Почему в отдельном потоке картинки сохраняются как белые прямоугольники, а в основном потоке - всё Ок?

15.09.2016, 19:32. Показов 3099. Ответов 15

Студворк — интернет-сервис помощи студентам
Всем привет, делаю функцию уменьшения картинок при помощи библиотеки GDI+, в отдельном потоке происходит уменьшение картинки и её сохранение на диск. Из главного потока только сбор путей файлов, передача их в экземпляр потока, и его запуск.
Причем, если сделать тоже самое в главном потоке, либо сказать главному - чтобы дожидался дополнительного - всё работает.

Вот код модуля потока
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
unit uDiminishPicsThread;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons,GDIPOBJ,Math,
  System.IOUtils,System.Types, Vcl.ComCtrls,uTestDiminishPics;
 
type
  TDiminishPicsThread = class(TThread)
  private
 
    FFilesInDir:TStringDynArray;
    FPicsExtensionsList:TStringList;
 
    FThreadStarter:TfTestDiminshPics;
 
    procedure GDIplusDiminishPic(FilePath: string);
    procedure LoadAAImageFromFile(FileName: String; W, H: Integer;
      Pic: TBitmap);
 
   public
   property FilesInDir:TStringDynArray read FFilesInDir write FFilesInDir;
 
   property PicsExtensionsList:TStringList read FPicsExtensionsList
   write FPicsExtensionsList;
 
   property ThreadStarter:TfTestDiminshPics read FThreadStarter write
   FThreadStarter;
 
  protected
    procedure Execute; override;
  end;
 
implementation
 
 
 
{ TDiminishPicsThread }
 
procedure TDiminishPicsThread.Execute;
var
  i: Integer;
  Ext: string;
begin
       FThreadStarter.ProgressBar1.Max:=High(FilesInDir);
 
        for i := 0 to High(FilesInDir) do
 
        begin
 
            //Increasing ProgressBar
            FThreadStarter.ProgressBar1.Position:=
            FThreadStarter.ProgressBar1.Position+1;
 
         //   Sleep(100);
 
            //Working with Files
            Ext:=ExtractFileExt( FilesInDir[i]);
 
            Ext:=AnsiLowerCase(Ext);
            if Pos(Ext,FPicsExtensionsList.Text)>0 then
            GDIplusDiminishPic(FilesInDir[i])
 
        end;
 
 
end;
 
 
 
 
procedure TDiminishPicsThread.GDIplusDiminishPic(FilePath:string);
var
  thumbnailPicsDir: string;
 
  bmp, bmpDiminished: TBItmap; twic:TWICImage;
 
  maxWidth:integer;
  maxHeight:integer;
 
  currentWidth:integer;
  currentHeight:integer;
 
  koeff:Extended;
  NewWidth: integer;
  NewHeight: integer;
  CurrentFileName: string;
  FileExtension: string;
  NewFileName: string;
 
begin
 
//Checks...
if not TFile.Exists(FilePath) then exit;
 
 
//Creating dir for Thumbs if not Existed
thumbnailPicsDir:=ExtractFileDir(Application.ExeName)+'\thumbnailPics';
if not TDirectory.Exists( thumbnailPicsDir) then
TDirectory.CreateDirectory(thumbnailPicsDir);
//----
 
//Getting FileExtension
FileExtension:=ExtractFileExt(FilePath);
 
//Setting MaxSize On the Exit...
      maxWidth:=50;
      maxHeight:=50;
 
 
        twic:=TWICImage.Create;
 
        bmp:= Tbitmap.Create;
        bmpDiminished:= Tbitmap.Create;
 
        try
 
            twic.LoadFromFile(FilePath);
            bmp.Assign(twic);
 
            currentWidth:=bmp.Width; currentHeight:=bmp.Height;
 
            //Calculating koeff
            if (currentWidth>maxWidth) or (currentHeight>maxHeight) then
            koeff:=Min(maxWidth/currentWidth,maxHeight/currentHeight) else
            koeff:=1;
 
            // New width and height
            NewWidth:=Trunc(koeff*currentWidth);
            NewHeight:=Trunc(koeff*currentHeight);
 
            CurrentFileName:=ExtractFileName(FilePath);
            NewFileName:=ChangeFileext( CurrentFileName, '_thumb.'+FileExtension ); // <<NewExtension
 
            LoadAAImageFromFile(FilePath,NewWidth,NewHeight,bmpDiminished);
            bmpDiminished.SaveToFile(thumbnailPicsDir+'\'+NewFileName);
 
        finally
          FreeAndNil(bmp);
          FreeAndNil(bmpDiminished);
          FreeAndNil(twic);
        //  ShowMessage('success');
        end;
 
 
end;
 
 
//-------------Diminish one pic---------------
procedure TDiminishPicsThread.LoadAAImageFromFile(FileName: String; W,H: Integer; Pic: TBitmap);
var ImageTemp: TGPImage;
graphicsGDIPlus: TGPGraphics;
begin
if FileExists(FileName) then
  begin
  Pic.Width:=W;
  Pic.Height:=H;
  graphicsGDIPlus:=TGPGraphics.Create (Pic.Canvas.Handle);
  ImageTemp:=TGPImage.Create(FileName );
  graphicsGDIPlus.DrawImage(ImageTemp , 0,0,W,H);
  ImageTemp.Free;
  graphicsGDIPlus.Free;
  end;
end;
 
 
 
end.
А вот запуск... так работает

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
procedure TfTestDiminshPics.bMultiGDIPlusClick(Sender: TObject);
 
var FilesInDir:TStringDynArray;
  i: Integer;
  Ext: string;
 
  iTick: Integer;
 
  DiminishPicsThread:TDiminishPicsThread;
 
begin
 
//Choosing only folders
FileOpenDialog.Options := [fdoPickFolders];
 
if FileOpenDialog.Execute then
//ShowMessage(FileOpenDialog.FileName);
 
FilesInDir:=
TDirectory.GetFiles(FileOpenDialog.FileName);
 
 
  //--------------Запускаем дополнительный поток в ручном режиме
 
if Length(FilesInDir)>0 then
 begin
 
  try
 
 
     //Creating additional thread
    DiminishPicsThread:=TDiminishPicsThread.Create(true);
    DiminishPicsThread.FreeOnTerminate:=False;
 
    //Transferring params to additional thread
    DiminishPicsThread.FilesInDir:=FilesInDir;
    DiminishPicsThread.PicsExtensionsList:=FPicsExtensionsList;
 
 
            //Creating additional thread
        DiminishPicsThread:=TDiminishPicsThread.Create(true);
        DiminishPicsThread.FreeOnTerminate:=false;
 
 
 
 
              //Transferring params to additional thread
          DiminishPicsThread.FilesInDir:=FilesInDir;
          DiminishPicsThread.PicsExtensionsList:=FPicsExtensionsList;
          DiminishPicsThread.ThreadStarter:=Self;
          DiminishPicsThread.Start;
 
        DiminishPicsThread.WaitFor();
     finally
    FreeAndNil(DiminishPicsThread);
  end;
 
 end;
 
end;
А вот так тоже работает, но вместо уменьшенных картинок получаю белые прямоугольники

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
...
 
  //Creating additional thread
    DiminishPicsThread:=TDiminishPicsThread.Create(true);
    DiminishPicsThread.FreeOnTerminate:=true;
 
    //Transferring params to additional thread
    DiminishPicsThread.FilesInDir:=FilesInDir;
    DiminishPicsThread.PicsExtensionsList:=FPicsExtensionsList;
 
 
            //Creating additional thread
        DiminishPicsThread:=TDiminishPicsThread.Create(true);
        DiminishPicsThread.FreeOnTerminate:=false;
 
 
 
 
              //Transferring params to additional thread
          DiminishPicsThread.FilesInDir:=FilesInDir;
          DiminishPicsThread.PicsExtensionsList:=FPicsExtensionsList;
          DiminishPicsThread.ThreadStarter:=Self;
          DiminishPicsThread.Start;
...
Подозреваю, что как-то не так работаю с библиотекой GDI+, я с ней раньше не работал никогда. Может кто знает как её в многопоточном режиме использовать?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.09.2016, 19:32
Ответы с готовыми решениями:

Создать приложение, в отдельном потоке вычисляющее значение w и непрерывно обновляющее его в потоке
Ребят, с потоками не работал не когда. Есть задание , я понимаю что хотят, а вот как сделать потоками хз . Создайте приложение, в...

Вывод картинки на панель в отдельном потоке
Метод run() объявлен в классе, который реализует интерфейс Runnable. tForSlides - атрибут этого же класса. public void run() { ...

Объсните, почему значение переменной в отдельном потоке другое и как его поменять?
вот фрагмент кода добавил msgbox и в первом случае переменная изменена а вот уже в новом потоке значение переменной такое как при...

15
 Аватар для BOGG ART
592 / 459 / 147
Регистрация: 09.12.2013
Сообщений: 2,385
Записей в блоге: 2
15.09.2016, 21:27
гм... С такими кусками неудобно, можете проект прикрепить?

Добавлено через 1 минуту
Цитата Сообщение от GringoV Посмотреть сообщение
в многопоточном режиме
Надо уточнить. Возможно доп.инициализация требуется. А что коды ошибок показывают?
0
16 / 16 / 1
Регистрация: 29.11.2014
Сообщений: 227
15.09.2016, 22:17  [ТС]
Вас услышал, держите проект, там всё в кучу, я пробовал разные способы уменьшения изображения. Мне нужно такой, чтобы создал более менее приемлемый thumbnail, скажем 100*100, и создал его быстро, так как фотографий большого качества достаточно много.

TestDiminishPics.zip
0
16 / 16 / 1
Регистрация: 29.11.2014
Сообщений: 227
15.09.2016, 22:19  [ТС]
Коды ошибок, вы имеете ввиду GetLastError? Или те, которые из обработки исключений?
Я просто ошибки отлавливаю через try except обычно, но в этом тестовом примере этого нет.

Добавлено через 1 минуту
После того как запустите - жмите на кнопку MultiGDIPlus - по ней можно всю цепочку отследить
0
 Аватар для BOGG ART
592 / 459 / 147
Регистрация: 09.12.2013
Сообщений: 2,385
Записей в блоге: 2
16.09.2016, 02:33
Ну для начала вот тут:
Цитата Сообщение от GringoV Посмотреть сообщение
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
//Creating additional thread
    DiminishPicsThread:=TDiminishPicsThread.Create(true);
    DiminishPicsThread.FreeOnTerminate:=true;
//Transferring params to additional thread
    DiminishPicsThread.FilesInDir:=FilesInDir;
    DiminishPicsThread.PicsExtensionsList:=FPicsExtensionsList;
//Creating additional thread
    DiminishPicsThread:=TDiminishPicsThread.Create(true);
    DiminishPicsThread.FreeOnTerminate:=false;
//Transferring params to additional thread
    DiminishPicsThread.FilesInDir:=FilesInDir;
    DiminishPicsThread.PicsExtensionsList:=FPicsExtensionsList;
    DiminishPicsThread.ThreadStarter:=Self;
    DiminishPicsThread.Start;
...
В строке 3 вы создали поток A. В строке 9 вы создали поток B, при этом затёрли значение переменной хранящей поток A.
В строке 15 вы запускаете поток B, а ещё чуть дальше ждёте WaitFor() завершения потока B. А что же с потерянным потоком A?

Потом - почему вы в потоке вызываете методы формы VCL и её компонентов где и как попало?

Что за TWICImage?
TWICImage is an encapsulation of a Microsoft Windows Imaging Component. TWICImage relies on DirectX runtime.
гм... гм... Но зачем вам это, если у вас GDI+?
У меня например вообще вылетает в трубу при TBitmap.Assign(TWICImage), не уверен из-за потоков или нет, так как не работал с этой фигнёю.

Добавлено через 10 минут
У вас и у формы и у потока есть метод с одинаковым именем GDIplusDiminishPic - зачем? Путаться в них?
Содержимое правда не сравнивал. Но почему вы в потоке пытаетесь лезть в метод формы, когда у потока свой такой же?

Добавлено через 2 минуты
Delphi
1
FThreadStarter.ProgressBar1.Max:=High(FilesInDir);
Это будет работать неправильно в любом случае, так как в папке может быть 27 файлов, а картинками из них являться 3 файла. В итоге Max получится 27, а Position 3. Хотя обработано всё.

Добавлено через 48 минут
Переделал с TWICImage на TPicture, ибо не ведаю особенностей первого. Было немного лень, и просто объявил новую переменную, поменял на неё где надо.
В итоге вышло что TWICImage просто создавался (ничего ниоткуда не загружая) и удалялся в finally через FreeAndNil.
И знаете чего? При вызове из потока оно залипало насмерть на FreeAndNil ! Выкинул к чертям TWICImage, стало работать без "заморозки". Но это не значит что остальное можно так и оставить.

З.Ы. может стоит отфильтровывать ещё и файлы содержащие "_thumb", а то у меня оно нарожало файлы вида "11_thumb_thumb_thumb.BMP".
0
16 / 16 / 1
Регистрация: 29.11.2014
Сообщений: 227
16.09.2016, 15:14  [ТС]
))))))))))
Полный разбор полетов!
Спасибо. Видно, да, что я тороплюсь)))) Щас переделаю и отпишусь.

Добавлено через 58 минут
По поводу создания 2 потоков - да, моя ошибка. Там должен был создаваться только один.

Цитата Сообщение от BOGG ART Посмотреть сообщение
Потом - почему вы в потоке вызываете методы формы VCL и её компонентов где и как попало?
Вы имеете ввиду, например вот это? В смысле, почему без объектов синхронизации?
Delphi
1
ThreadStarter.GDIplusDiminishPic(FilesInDir[i])
Дело в том, что это тестовый пример. А так да, согласен. Как минимум критическую секцию над поставить.
Цитата Сообщение от BOGG ART Посмотреть сообщение
Что за TWICImage?
Это формат для загрузки разных типов изображений, jpg, jpeg, png и так далее.
Я с GDI+ 2 день работаю, поэтому не знал многих вещей, в частности, как с помощью неё загружать изображения из файлов разных форматов, а twic вроде как знаком был.

Цитата Сообщение от BOGG ART Посмотреть сообщение
У вас и у формы и у потока есть метод с одинаковым именем GDIplusDiminishPic - зачем? Путаться в них?
Содержимое правда не сравнивал. Но почему вы в потоке пытаетесь лезть в метод формы, когда у потока свой такой же?
Это я экспериментировал, код там должен быть идентичный. Думал, может из за этого белые прямоугольники
Цитата Сообщение от BOGG ART Посмотреть сообщение
Переделал с TWICImage на TPicture, ибо не ведаю особенностей первого. Было немного лень, и просто объявил новую переменную, поменял на неё где надо.
В итоге вышло что TWICImage просто создавался (ничего ниоткуда не загружая) и удалялся в finally через FreeAndNil.
И знаете чего? При вызове из потока оно залипало насмерть на FreeAndNil ! Выкинул к чертям TWICImage, стало работать без "заморозки". Но это не значит что остальное можно так и оставить.

То есть вы загружаете в TPicture? Примерно таким образом?
Delphi
1
2
Picture.LoadFromFile(FilePath);
            bmp.Assign(Picture.Bitmap);
Я попробовал так, првдварительно добавив в uses PNGImage,Jpeg, запустил - оно как бы работает, но файлы с размером 0 байт.

Добавлено через 49 минут
В общем, походил я с отладчиком, проблема следующая
-Если в основном потоке сделать так...
Delphi
1
2
3
4
5
...  
Picture.LoadFromFile(FilePath);
            bmp.Assign(Picture.Bitmap);
               currentWidth:=bmp.Width; currentHeight:=bmp.Height;
...
то всё будет в порядке, но если тоже самое сделать в дополнительном потоке, то bmp.Width показывает 0

Почему так происходит? LoadFromFile не срабатывает?

Добавлено через 32 секунды
Собственно отсюда и все остальные проблемы - картинка не поступает для дальнейшей обработки

Добавлено через 12 минут
Думал что то с синхронизацией. Добавил критическую секцию - но видимо дело не в этом. Суть в том, что картинка не загружается в методе LoadFormFile в дополнительном потоке...

Добавлено через 46 минут
Переписал через StretchDraw - заработало,
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
procedure TDiminishPicsThread.DiminishPic(FilePath:string);
var
  thumbnailPicsDir: string;
 
  bmp, bmpDiminished: TBItmap; twic:TWICImage;
 
  maxWidth:integer;
  maxHeight:integer;
 
  currentWidth:integer;
  currentHeight:integer;
 
  koeff:Extended;
  NewWidth: integer;
  NewHeight: integer;
  CurrentFileName: string;
  FileExtension: string;
  NewFileName: string;
 
  Picture:TPicture;
  ms: TMemoryStream;
  size:int64;
 
 
begin
 
//Checks...
if not TFile.Exists(FilePath) then exit;
 
 
//Creating dir for Thumbs if not Existed
thumbnailPicsDir:=ExtractFileDir(Application.ExeName)+'\thumbnailPics';
if not TDirectory.Exists( thumbnailPicsDir) then
TDirectory.CreateDirectory(thumbnailPicsDir);
//----
 
//Getting FileExtension
FileExtension:=ExtractFileExt(FilePath);
 
//Setting MaxSize On the Exit...
      maxWidth:=50;
      maxHeight:=50;
 
 
        twic:=TWICImage.Create;
 
        bmp:= Tbitmap.Create;
        bmpDiminished:= Tbitmap.Create;
 
 
        try
 
             twic.LoadFromFile(FilePath);
             bmp.Assign(twic);
 
             currentWidth:=bmp.Width; currentHeight:=bmp.Height;
 
            //Calculating koeff
            if (currentWidth>maxWidth) or (currentHeight>maxHeight) then
            koeff:=Min(maxWidth/currentWidth,maxHeight/currentHeight) else
            koeff:=1;
 
            // New width and height
            NewWidth:=Trunc(koeff*currentWidth);
            NewHeight:=Trunc(koeff*currentHeight);
 
            CurrentFileName:=ExtractFileName(FilePath);
            NewFileName:=ChangeFileext( CurrentFileName, '_thumb'+FileExtension ); // <<NewExtension
 
 
           bmpDiminished.Width:=NewWidth; bmpDiminished.Height:=NewHeight;
           bmpDiminished.Canvas.StretchDraw(Rect(0, 0, NewWidth, NewHeight), bmp);
 
            bmpDiminished.SaveToFile(thumbnailPicsDir+'\'+NewFileName);
 
        finally
 
 
          FreeAndNil(twic);
 
          FreeAndNil(bmp);
          FreeAndNil(bmpDiminished);
 
 
 
         // FreeAndNil(twic);
        //  ShowMessage('success');
        end;
 
 
end;
Добавлено через 4 часа 42 минуты
В общем, вот что... получилось... Код работает... Можно там поработать с качеством, скоростью, но мою задачу он решил, и я пока движусь далее, но если кому понадобится...

Запуск потока...
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
procedure TfTestDiminshPics.bMultiDiminishPicsClick(Sender: TObject);
 
var FilesInDir,FilesInDirFiltered:TStringDynArray;
  i: Integer;
  Ext: string;
 
  DiminishPicsThread:TDiminishPicsThread;
 
  AllowedExtensions:string;
 
begin
 
AllowedExtensions:='.bmp,.jpg,.jpeg,.png,.tiff';
 
    //Choosing only folders
    FileOpenDialog.Options := [fdoPickFolders];
 
    // Getting All files from dir
    if FileOpenDialog.Execute then
    FilesInDir:=
    TDirectory.GetFiles(FileOpenDialog.FileName);
 
 
           //Filtering only pics... in FilesInDirFiltered
    for i := 0 to High(FilesInDir) do
    begin
            Ext:=AnsiLowerCase(ExtractFileExt(FilesInDir[i]));
            if Pos(Ext,AllowedExtensions)>0 then
 
            begin
              SetLength(FilesInDirFiltered,Length(FilesInDirFiltered)+1);
              FilesInDirFiltered[ High(FilesInDirFiltered) ]:=FilesInDir[i];
            end;
 
 
    end;
 
 
 
      //--------------Starting additional thread
 
    if Length(FilesInDir)>0 then
     begin
 
        ProgressBar.Position:=0;
 
         //Creating additional thread
        DiminishPicsThread:=TDiminishPicsThread.Create(true);
        DiminishPicsThread.FreeOnTerminate:=true;
        DiminishPicsThread.Priority:=tpHigher;
 
 
 
                  //Transferring params to additional thread
 
              DiminishPicsThread.ThreadStarter:=Self;
              DiminishPicsThread.FilesInDir:=FilesInDirFiltered;
              DiminishPicsThread.MaxWidth:=50;
              DiminishPicsThread.MaxHeight:=50;
 
 
 
              DiminishPicsThread.Start;
 
 
 
     end;
 
 
end;
Сам код потока...
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
unit uDiminishPicsThread;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons,GDIPOBJ,Math,
  System.IOUtils,System.Types, Vcl.ComCtrls,uTestDiminishPics;
 
type
  TDiminishPicsThread = class(TThread)
  private
 
 
 
 
    FThreadStarter:TfTestDiminshPics;
    fEx : Exception;
    FPicsArray:TStringDynArray;
 
    FMaxWidth:integer;
    FMaxHeight:integer;
 
 
    procedure QueryError;
 
    procedure GDIplusDiminishPic(FilePath: string);
    procedure LoadAAImageFromFile(FileName: String; W, H: Integer;
      Pic: TBitmap);
    procedure LoadFromFile(FilePath: string; var twic:twicimage);
    procedure DiminishPic(FilePath: string);
 
   public
 
 
 
   property FilesInDir:TStringDynArray read FPicsArray write FPicsArray;
 
 
   property ThreadStarter:TfTestDiminshPics read FThreadStarter write
   FThreadStarter;
 
 
   property MaxWidth:integer read FMaxWidth write FMaxWidth;
   property MaxHeight:integer read FMaxHeight write FMaxHeight;
 
 
 
  protected
    procedure Execute; override;
  end;
 
implementation
 
 
 
{ TDiminishPicsThread }
 
procedure TDiminishPicsThread.Execute;
var
  iTick:integer;
  i: Integer;
 
begin
 
 
 
       FThreadStarter.ProgressBar.Max:=High(FilesInDir);
 
 
 
     iTick:=GetTickCount;
 
        for i := 0 to High(FilesInDir) do
 
        begin
 
 
          // Anonymously updating progressBar
                       Synchronize(
            procedure
            begin
                FThreadStarter.ProgressBar.Position:=
                  FThreadStarter.ProgressBar.Position+1;
            end
        );
 
 
               DiminishPic(FilesInDir[i]);
         //   ( GDIplusDiminishPic(FilesInDir[i])); // <<Works unstable Randomly
 
 
 
                  // Anonymously updating caption
               Synchronize(
          procedure
          begin
            ThreadStarter.Caption:=
            'Npics / total = '+i.ToString+' / ' +length(FPicsArray).ToString+
            ' Time(ms)='+IntToStr(GetTickCount-iTick);
          end
          );
 
 
 
        end;
 
 
 
 
    fEx := ExceptObject as Exception;
    Synchronize( QueryError );
 
 
end;
 
 
 
 
procedure TDiminishPicsThread.LoadFromFile(FilePath:string; var twic:twicimage);
begin
twic.LoadFromFile(FilePath);
end;
 
 
procedure TDiminishPicsThread.QueryError;
begin
Application.OnException(Self,fex);
end;
 
procedure TDiminishPicsThread.GDIplusDiminishPic(FilePath:string);
var
  thumbnailPicsDir: string;
 
  bmp, bmpDiminished: TBItmap; twic:TWICImage;
 
  maxWidth:integer;
  maxHeight:integer;
 
  currentWidth:integer;
  currentHeight:integer;
 
  koeff:Extended;
  NewWidth: integer;
  NewHeight: integer;
  CurrentFileName: string;
  FileExtension: string;
  NewFileName: string;
 
begin
 
//Checks...
if not TFile.Exists(FilePath) then exit;
 
 
//Creating dir for Thumbs if not Existed
thumbnailPicsDir:=ExtractFileDir(Application.ExeName)+'\thumbnailPics';
if not TDirectory.Exists( thumbnailPicsDir) then
TDirectory.CreateDirectory(thumbnailPicsDir);
//----
 
//Getting FileExtension
FileExtension:=ExtractFileExt(FilePath);
 
//Setting MaxSize On the Exit...
      maxWidth:=50;
      maxHeight:=50;
 
 
        twic:=TWICImage.Create;
 
        bmp:= Tbitmap.Create;
        bmpDiminished:= Tbitmap.Create;
 
        try
 
            twic.LoadFromFile(FilePath);
            bmp.Assign(twic);
 
            currentWidth:=bmp.Width; currentHeight:=bmp.Height;
 
            //Calculating koeff
            if (currentWidth>maxWidth) or (currentHeight>maxHeight) then
            koeff:=Min(maxWidth/currentWidth,maxHeight/currentHeight) else
            koeff:=1;
 
            // New width and height
            NewWidth:=Trunc(koeff*currentWidth);
            NewHeight:=Trunc(koeff*currentHeight);
 
            CurrentFileName:=ExtractFileName(FilePath);
            NewFileName:=ChangeFileext( CurrentFileName, '_thumb.'+FileExtension ); // <<NewExtension
 
            LoadAAImageFromFile(FilePath,NewWidth,NewHeight,bmpDiminished);
            bmpDiminished.SaveToFile(thumbnailPicsDir+'\'+NewFileName);
 
        finally
          FreeAndNil(bmp);
          FreeAndNil(bmpDiminished);
          FreeAndNil(twic);
        //  ShowMessage('success');
        end;
 
 
end;
 
 
//-------------Diminish one pic GDI+---------------
procedure TDiminishPicsThread.LoadAAImageFromFile(FileName: String; W,H: Integer; Pic: TBitmap);
var ImageTemp: TGPImage;
graphicsGDIPlus: TGPGraphics;
begin
if FileExists(FileName) then
  begin
  Pic.Width:=W;
  Pic.Height:=H;
  graphicsGDIPlus:=TGPGraphics.Create (Pic.Canvas.Handle);
 
  ImageTemp:=TGPImage.Create(FileName ); // Trouble here
 
  graphicsGDIPlus.DrawImage(ImageTemp , 0,0,W,H);
  ImageTemp.Free;
  graphicsGDIPlus.Free;
  end;
end;
 
 
 
//-------------Diminish one pic Stretch---------------
procedure TDiminishPicsThread.DiminishPic(FilePath:string);
var
  thumbnailPicsDir: string;
 
  bmp, bmpDiminished: TBItmap; twic:TWICImage;
 
  maxWidth:integer;
  maxHeight:integer;
 
  currentWidth:integer;
  currentHeight:integer;
 
  koeff:Extended;
  NewWidth: integer;
  NewHeight: integer;
  CurrentFileName: string;
  FileExtension: string;
  NewFileName: string;
 
  Picture:TPicture;
  ms: TMemoryStream;
  size:int64;
 
 
begin
 
//Checks...
if not TFile.Exists(FilePath) then exit;
 
 
//Creating dir for Thumbs if not Existed
thumbnailPicsDir:=ExtractFileDir(Application.ExeName)+'\thumbnailPics';
if not TDirectory.Exists( thumbnailPicsDir) then
TDirectory.CreateDirectory(thumbnailPicsDir);
//----
 
//Getting FileExtension
FileExtension:=ExtractFileExt(FilePath);
 
//Setting MaxSize On the Exit...
      maxWidth:=FMaxWidth;
      maxHeight:=FMaxHeight;
 
 
        twic:=TWICImage.Create;
 
        bmp:= Tbitmap.Create;
        //bmp.PixelFormat:=pf32bit;
        bmp.AlphaFormat:=afDefined;
 
        bmpDiminished:= Tbitmap.Create;
        //bmpDiminished.PixelFormat:=pf32bit;
        bmpDiminished.AlphaFormat:=afDefined;
 
 
        try
 
             twic.LoadFromFile(FilePath);
             bmp.Assign(twic);
 
             currentWidth:=bmp.Width; currentHeight:=bmp.Height;
 
            //Calculating koeff
            if (currentWidth>maxWidth) or (currentHeight>maxHeight) then
            koeff:=Min(maxWidth/currentWidth,maxHeight/currentHeight) else
            koeff:=1;
 
            // New width and height
            NewWidth:=Trunc(koeff*currentWidth);
            NewHeight:=Trunc(koeff*currentHeight);
 
            CurrentFileName:=ExtractFileName(FilePath);
            NewFileName:=ChangeFileext( CurrentFileName, '_thumb'+FileExtension ); // <<NewExtension
 
 
           bmpDiminished.Width:=NewWidth; bmpDiminished.Height:=NewHeight;
           bmpDiminished.Canvas.StretchDraw(Rect(0, 0, NewWidth, NewHeight), bmp);
 
            bmpDiminished.SaveToFile(thumbnailPicsDir+'\'+NewFileName);
 
        finally
 
 
          FreeAndNil(twic);
 
          FreeAndNil(bmp);
          FreeAndNil(bmpDiminished);
 
 
 
         // FreeAndNil(twic);
        //  ShowMessage('success');
        end;
 
 
end;
 
 
 
end.
0
16 / 16 / 1
Регистрация: 29.11.2014
Сообщений: 227
16.09.2016, 15:23  [ТС]
В общем, вот что... получилось... Код работает... Можно там поработать с качеством, скоростью, но мою задачу он решил, и я пока движусь далее, но если кому понадобится...

Запуск потока...
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
procedure TfTestDiminshPics.bMultiDiminishPicsClick(Sender: TObject);
 
var FilesInDir,FilesInDirFiltered:TStringDynArray;
  i: Integer;
  Ext: string;
 
  DiminishPicsThread:TDiminishPicsThread;
 
  AllowedExtensions:string;
 
begin
 
AllowedExtensions:='.bmp,.jpg,.jpeg,.png,.tiff';
 
    //Choosing only folders
    FileOpenDialog.Options := [fdoPickFolders];
 
    // Getting All files from dir
    if FileOpenDialog.Execute then
    FilesInDir:=
    TDirectory.GetFiles(FileOpenDialog.FileName);
 
 
           //Filtering only pics... in FilesInDirFiltered
 
 SetLength(FilesInDirFiltered,0); // nulling...
   
for i := 0 to High(FilesInDir) do
    begin
            Ext:=AnsiLowerCase(ExtractFileExt(FilesInDir[i]));
            if Pos(Ext,AllowedExtensions)>0 then
 
            begin
              SetLength(FilesInDirFiltered,Length(FilesInDirFiltered)+1);
              FilesInDirFiltered[ High(FilesInDirFiltered) ]:=FilesInDir[i];
            end;
 
 
    end;
 
 
 
      //--------------Starting additional thread
 
    if Length(FilesInDir)>0 then
     begin
 
        ProgressBar.Position:=0;
 
         //Creating additional thread
        DiminishPicsThread:=TDiminishPicsThread.Create(true);
        DiminishPicsThread.FreeOnTerminate:=true;
        DiminishPicsThread.Priority:=tpHigher;
 
 
 
                  //Transferring params to additional thread
 
              DiminishPicsThread.ThreadStarter:=Self;
              DiminishPicsThread.FilesInDir:=FilesInDirFiltered;
              DiminishPicsThread.MaxWidth:=50;
              DiminishPicsThread.MaxHeight:=50;
 
 
 
              DiminishPicsThread.Start;
 
 
 
     end;
 
 
end;
Сам код потока...
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
unit uDiminishPicsThread;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons,GDIPOBJ,Math,
  System.IOUtils,System.Types, Vcl.ComCtrls,uTestDiminishPics;
 
type
  TDiminishPicsThread = class(TThread)
  private
 
 
 
 
    FThreadStarter:TfTestDiminshPics;
    fEx : Exception;
    FPicsArray:TStringDynArray;
 
    FMaxWidth:integer;
    FMaxHeight:integer;
 
 
    procedure QueryError;
 
    procedure GDIplusDiminishPic(FilePath: string);
    procedure LoadAAImageFromFile(FileName: String; W, H: Integer;
      Pic: TBitmap);
    procedure LoadFromFile(FilePath: string; var twic:twicimage);
    procedure DiminishPic(FilePath: string);
 
   public
 
 
 
   property FilesInDir:TStringDynArray read FPicsArray write FPicsArray;
 
 
   property ThreadStarter:TfTestDiminshPics read FThreadStarter write
   FThreadStarter;
 
 
   property MaxWidth:integer read FMaxWidth write FMaxWidth;
   property MaxHeight:integer read FMaxHeight write FMaxHeight;
 
 
 
  protected
    procedure Execute; override;
  end;
 
implementation
 
 
 
{ TDiminishPicsThread }
 
procedure TDiminishPicsThread.Execute;
var
  iTick:integer;
  i: Integer;
 
begin
 
 
 
       FThreadStarter.ProgressBar.Max:=High(FilesInDir);
 
 
 
     iTick:=GetTickCount;
 
        for i := 0 to High(FilesInDir) do
 
        begin
 
 
          // Anonymously updating progressBar
                       Synchronize(
            procedure
            begin
                FThreadStarter.ProgressBar.Position:=
                  FThreadStarter.ProgressBar.Position+1;
            end
        );
 
 
               DiminishPic(FilesInDir[i]);
         //   ( GDIplusDiminishPic(FilesInDir[i])); // <<Works unstable Randomly
 
 
 
                  // Anonymously updating caption
               Synchronize(
          procedure
          begin
            ThreadStarter.Caption:=
            'Npics / total = '+i.ToString+' / ' +length(FPicsArray).ToString+
            ' Time(ms)='+IntToStr(GetTickCount-iTick);
          end
          );
 
 
 
        end;
 
 
 
 
    fEx := ExceptObject as Exception;
    Synchronize( QueryError );
 
 
end;
 
 
 
 
procedure TDiminishPicsThread.LoadFromFile(FilePath:string; var twic:twicimage);
begin
twic.LoadFromFile(FilePath);
end;
 
 
procedure TDiminishPicsThread.QueryError;
begin
Application.OnException(Self,fex);
end;
 
procedure TDiminishPicsThread.GDIplusDiminishPic(FilePath:string);
var
  thumbnailPicsDir: string;
 
  bmp, bmpDiminished: TBItmap; twic:TWICImage;
 
  maxWidth:integer;
  maxHeight:integer;
 
  currentWidth:integer;
  currentHeight:integer;
 
  koeff:Extended;
  NewWidth: integer;
  NewHeight: integer;
  CurrentFileName: string;
  FileExtension: string;
  NewFileName: string;
 
begin
 
//Checks...
if not TFile.Exists(FilePath) then exit;
 
 
//Creating dir for Thumbs if not Existed
thumbnailPicsDir:=ExtractFileDir(Application.ExeName)+'\thumbnailPics';
if not TDirectory.Exists( thumbnailPicsDir) then
TDirectory.CreateDirectory(thumbnailPicsDir);
//----
 
//Getting FileExtension
FileExtension:=ExtractFileExt(FilePath);
 
//Setting MaxSize On the Exit...
      maxWidth:=50;
      maxHeight:=50;
 
 
        twic:=TWICImage.Create;
 
        bmp:= Tbitmap.Create;
        bmpDiminished:= Tbitmap.Create;
 
        try
 
            twic.LoadFromFile(FilePath);
            bmp.Assign(twic);
 
            currentWidth:=bmp.Width; currentHeight:=bmp.Height;
 
            //Calculating koeff
            if (currentWidth>maxWidth) or (currentHeight>maxHeight) then
            koeff:=Min(maxWidth/currentWidth,maxHeight/currentHeight) else
            koeff:=1;
 
            // New width and height
            NewWidth:=Trunc(koeff*currentWidth);
            NewHeight:=Trunc(koeff*currentHeight);
 
            CurrentFileName:=ExtractFileName(FilePath);
            NewFileName:=ChangeFileext( CurrentFileName, '_thumb.'+FileExtension ); // <<NewExtension
 
            LoadAAImageFromFile(FilePath,NewWidth,NewHeight,bmpDiminished);
            bmpDiminished.SaveToFile(thumbnailPicsDir+'\'+NewFileName);
 
        finally
          FreeAndNil(bmp);
          FreeAndNil(bmpDiminished);
          FreeAndNil(twic);
        //  ShowMessage('success');
        end;
 
 
end;
 
 
//-------------Diminish one pic GDI+---------------
procedure TDiminishPicsThread.LoadAAImageFromFile(FileName: String; W,H: Integer; Pic: TBitmap);
var ImageTemp: TGPImage;
graphicsGDIPlus: TGPGraphics;
begin
if FileExists(FileName) then
  begin
  Pic.Width:=W;
  Pic.Height:=H;
  graphicsGDIPlus:=TGPGraphics.Create (Pic.Canvas.Handle);
 
  ImageTemp:=TGPImage.Create(FileName ); // Trouble here
 
  graphicsGDIPlus.DrawImage(ImageTemp , 0,0,W,H);
  ImageTemp.Free;
  graphicsGDIPlus.Free;
  end;
end;
 
 
 
//-------------Diminish one pic Stretch---------------
procedure TDiminishPicsThread.DiminishPic(FilePath:string);
var
  thumbnailPicsDir: string;
 
  bmp, bmpDiminished: TBItmap; twic:TWICImage;
 
  maxWidth:integer;
  maxHeight:integer;
 
  currentWidth:integer;
  currentHeight:integer;
 
  koeff:Extended;
  NewWidth: integer;
  NewHeight: integer;
  CurrentFileName: string;
  FileExtension: string;
  NewFileName: string;
 
  Picture:TPicture;
  ms: TMemoryStream;
  size:int64;
 
 
begin
 
//Checks...
if not TFile.Exists(FilePath) then exit;
 
 
//Creating dir for Thumbs if not Existed
thumbnailPicsDir:=ExtractFileDir(Application.ExeName)+'\thumbnailPics';
if not TDirectory.Exists( thumbnailPicsDir) then
TDirectory.CreateDirectory(thumbnailPicsDir);
//----
 
//Getting FileExtension
FileExtension:=ExtractFileExt(FilePath);
 
//Setting MaxSize On the Exit...
      maxWidth:=FMaxWidth;
      maxHeight:=FMaxHeight;
 
 
        twic:=TWICImage.Create;
 
        bmp:= Tbitmap.Create;
        //bmp.PixelFormat:=pf32bit;
        bmp.AlphaFormat:=afDefined;
 
        bmpDiminished:= Tbitmap.Create;
        //bmpDiminished.PixelFormat:=pf32bit;
        bmpDiminished.AlphaFormat:=afDefined;
 
 
        try
 
             twic.LoadFromFile(FilePath);
             bmp.Assign(twic);
 
             currentWidth:=bmp.Width; currentHeight:=bmp.Height;
 
            //Calculating koeff
            if (currentWidth>maxWidth) or (currentHeight>maxHeight) then
            koeff:=Min(maxWidth/currentWidth,maxHeight/currentHeight) else
            koeff:=1;
 
            // New width and height
            NewWidth:=Trunc(koeff*currentWidth);
            NewHeight:=Trunc(koeff*currentHeight);
 
            CurrentFileName:=ExtractFileName(FilePath);
            NewFileName:=ChangeFileext( CurrentFileName, '_thumb'+FileExtension ); // <<NewExtension
 
 
           bmpDiminished.Width:=NewWidth; bmpDiminished.Height:=NewHeight;
           bmpDiminished.Canvas.StretchDraw(Rect(0, 0, NewWidth, NewHeight), bmp);
 
            bmpDiminished.SaveToFile(thumbnailPicsDir+'\'+NewFileName);
 
        finally
 
 
          FreeAndNil(twic);
 
          FreeAndNil(bmp);
          FreeAndNil(bmpDiminished);
 
 
 
         // FreeAndNil(twic);
        //  ShowMessage('success');
        end;
 
 
end;
 
 
 
end.
Добавлено через 8 минут
В итоге я ушел от GDI+, использовал обычный StretchDraw. С GDI+ появлялись белые прямоугольники, постоянно, вместо картинок, насколько я раскопал, проблема в
Delphi
1
ImageTemp:=TGPImage.Create(FileName ); // Trouble here
Путь этой функции указывается правильно. И если запустить её в основном потоке, то всё работает на ура, а вот если в дополнительный thread, то белые прямоугольники вместо картинок.
На этом данную тему для себя закрываю. Всем удачи в кодинге !!!

P.S. Кстати, как тут поменять ник? Писал в админку - тишина.
0
16 / 16 / 1
Регистрация: 29.11.2014
Сообщений: 227
16.09.2016, 15:27  [ТС]
Прикладываю прожект
TestDiminishPics.7z
0
 Аватар для BOGG ART
592 / 459 / 147
Регистрация: 09.12.2013
Сообщений: 2,385
Записей в блоге: 2
16.09.2016, 16:52
Цитата Сообщение от GringoV Посмотреть сообщение
Я попробовал так, првдварительно добавив в uses PNGImage,Jpeg, запустил - оно как бы работает, но файлы с размером 0 байт.
Да, только не "Picture.Bitmap", а "Picture.Graphic". Просто вы хотели работать через GDI+, а тот может сам грузить и сохранять основные форматы.
У меня работало через GDI+ вполне нормально.

Посмотрю проект чуть позже. Может есть смысл создать новый проект и частями аккуратно перенести в него код из первого, чтоб ничего лишнего не было.
0
16 / 16 / 1
Регистрация: 29.11.2014
Сообщений: 227
17.09.2016, 01:12  [ТС]
Да, я понял уже, но позже, что можно было напрямую грузить в нее. А GDI+ мощная штука!!! Со временем разберусь.

Пронаблюдал интересное явление, вот в этой процедурке
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//-------------Diminish one pic GDI+---------------
procedure TDiminishPicsThread.LoadAAImageFromFile(FileName: String; W,H: Integer; Pic: TBitmap);
var ImageTemp: TGPImage;
graphicsGDIPlus: TGPGraphics;
begin
if FileExists(FileName) then
  begin
  Pic.Width:=W;
  Pic.Height:=H;
  graphicsGDIPlus:=TGPGraphics.Create (Pic.Canvas.Handle);
 
  ImageTemp:=TGPImage.Create(FileName ); // Trouble here
 
  graphicsGDIPlus.DrawImage(ImageTemp , 0,0,W,H);
  ImageTemp.Free;
  graphicsGDIPlus.Free;
  end;
end;
В строке
Delphi
1
 ImageTemp:=TGPImage.Create(FileName ); // Trouble here
Если её в основном потоке запускать - всё Ок, а если в дополнительном - она не грузит из файла.... От этого и шли белые квадраты. Пока загадка для меня.
0
пофигист широкого профиля
4769 / 3204 / 862
Регистрация: 15.07.2013
Сообщений: 18,608
17.09.2016, 02:10
Цитата Сообщение от GringoV Посмотреть сообщение
Сам код потока...
Ну вот уже сразу.
В первой строчке кода метода Execute потока идет обращение к компоненту VCL формы
Цитата Сообщение от GringoV Посмотреть сообщение
FThreadStarter.ProgressBar.Max:=High(Fil esInDir);
А это недопустимо!
0
16 / 16 / 1
Регистрация: 29.11.2014
Сообщений: 227
17.09.2016, 02:13  [ТС]
Цитата Сообщение от northener Посмотреть сообщение
А это недопустимо!
Во всех случаях?
0
пофигист широкого профиля
4769 / 3204 / 862
Регистрация: 15.07.2013
Сообщений: 18,608
17.09.2016, 02:19
Цитата Сообщение от GringoV Посмотреть сообщение
Во всех случаях?
Во всех.
Исключения допустимы только для "хакеров высокой квалификации".
0
16 / 16 / 1
Регистрация: 29.11.2014
Сообщений: 227
17.09.2016, 02:21  [ТС]
В каких же, интересно, допустимы исключения?
0
пофигист широкого профиля
4769 / 3204 / 862
Регистрация: 15.07.2013
Сообщений: 18,608
17.09.2016, 02:30
Цитата Сообщение от GringoV Посмотреть сообщение
В каких же, интересно, допустимы исключения?
Я что должен дать курс лекций по этому вопросу с освещением всех его деталей?
Ну на всякий случай. В двух словах этот вопрос не объяснить.
0
16 / 16 / 1
Регистрация: 29.11.2014
Сообщений: 227
17.09.2016, 02:50  [ТС]
Цитата Сообщение от northener Посмотреть сообщение
Я что должен дать курс лекций по этому вопросу с освещением всех его деталей?
Ни в коем случае! Ваше время бесценно. Спасибо, что снизошли, о Великий!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.09.2016, 02:50
Помогаю со студенческими работами здесь

Загрузка в ImageView картинки по ссылке в отдельном потоке. Исправить код
Здравствуйте! Пытаюсь загрузить картинку по ссылке из инета в ImageView в отдельном потоке. Поток реализовывал путем перегрузки метода run,...

Как реализовать генерацию события в основном потоке?
Всем здравствуйте! У меня есть некий класс, в котором в отдельном потоке выполняется циклическая операция, после каждой с итераций...

Как вызвать асинхронную функцию в основном потоке и дождаться результата ?
Ситуация такая : запускаю фоновый поток из основного (интерфейсного) для проверки обновления Task.Run(()=&gt;CheckUpdate()); В...

При запуске метода с параметром делегатом в отдельном потоке виснет все приложение
public partial class MainWindow : Window { public delegate void ServerStart(Server.Send t); public...

Как записать строку созданную в основном потоке в texbox работающем в backgroundworker?
Здравствуйте, попытаюсь вкратце описать суть проблемы. У меня есть 8-ми канальный измеритель температуры, каждую секунду я хочу опрашивать...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru