Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Графика и игры
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 23.04.2013, 19:42
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию Работа с изображениями в потоке

Вот код, если он как обычная процедура то работает, если как поток то не работает!!! Нужен поток не люблю когда что нибудь тормозит!!!
Код:
procedure TCapth.execute;
var
i,x,y,l,j,iz:integer;
s:integer;
stop:Boolean;
cap:String;
proz,posx,posy,all:Integer;
begin
  inherited;
   cap:='';
 for posx := 3 to 77 do begin
 for posy := 3 to 15 do begin
 s:=0;
 iz:=3;

 repeat
    iz:=iz+1;
    all:=0;
    s:=0;
    proz:=0;
 x:=TImage(Form1.FindComponent('Image'+IntToStr(iz))).Width-1;
 y:=TImage(Form1.FindComponent('Image'+IntToStr(iz))).Height-1;
  for l := 0 to x do begin
 for j := 0 to y do begin

 if (TImage(Form1.FindComponent('Image'+IntToStr(iz))).Canvas.Pixels[l,j]<>RGB(255,255,255)) then begin
  all:=all+1;
 end;
 end;
 end;

 for l := 0 to x do begin
 for j := 0 to y do begin
if (TImage(Form1.FindComponent('Image'+IntToStr(iz))).Canvas.Pixels[l,j]=Form1.image2.Canvas.Pixels[l+posx,j+posy]) 
and   (TImage(Form1.FindComponent('Image'+IntToStr(iz))).Canvas.Pixels[l,j]<>RGB(255,255,255)) then
begin
s:=s+1;
end;
 end;
 end;
 proz:=round(s/all*100);

  if proz>60 then begin
  case iz of
  3..7:cap:=cap+'0';
  8..12:cap:=cap+'1';
  13..17:cap:=cap+'2';
  18..22:cap:=cap+'3';
  23..27:cap:=cap+'4';
  28..32:cap:=cap+'5';
  33..37:cap:=cap+'6';
  38..42:cap:=cap+'7';
  43..47:cap:=cap+'8';
  48..52:cap:=cap+'9';
  end;
  end;

     until iz=52;
 end;
 end;

   Form1.sEdit2.Text:=cap;
end;

Последний раз редактировалось ProDaNTe, 24.04.2013 в 07:41.
Ответить с цитированием
  #2  
Старый 23.04.2013, 20:12
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от ProDaNTe
...если он как обычная процедура то работает, если как поток то не работает...
Нужно убрать обращения из потока к статическим компонентам расположенным на форме, заменив их динамически создаваемыми на время выполнения и передачи результата в конце.

З.Ы. И пжлст, отформатируйте код на предмет переноса строк в рамках редактора, а то на экране он расползается за его пределы, а это не красиво.

Последний раз редактировалось Alegun, 23.04.2013 в 22:37.
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
ProDaNTe (24.04.2013)
  #3  
Старый 24.04.2013, 06:33
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

Цитата:
Нужно убрать обращения из потока к статическим компонентам расположенным на форме, заменив их динамически создаваемыми на время выполнения и передачи результата в конце.
Так я создам динамически объект, а от куда брать изображение? с файла, не будет ли это очень медленно работать? Посоветуй каким образом сделать лучше и быстрее, заранее спасибо!
Ответить с цитированием
  #4  
Старый 24.04.2013, 07:11
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Зачем с файла если оно и так уже в имидж загружено. Динамически создать, затем присвоить imageN.Picture:= image1.Picture а дальше как обычно, быстрее не будет, просто из потока не желательно к статике обращаться, может быть пересечение с другим/основным потоком, что чревато непредсказуемостью.

Оффтоп:
З.Ы. Ещё раз прошу нижайше, пжлст, нажав на правку около первого поста, в районе 34й строки кода не соблаговолите ли вы, млстлвгсдр , где-то около оператора and жимануть на ентер чтоб строчку разбить, ну правда, не красиво.
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
ProDaNTe (24.04.2013)
  #5  
Старый 24.04.2013, 07:47
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

Цитата:
Ещё раз прошу нижайше, пжлст, нажав на правку около первого поста, в районе 34й строки кода не соблаговолите ли вы, млстлвгсдр , где-то около оператора and жимануть на ентер чтоб строчку разбить, ну правда, не красиво.
Извени не преверженец красивого и грамотного кода, но раз просишь то хорошо!
Цитата:
Динамически создать, затем присвоить imageN.Picture:= image1.Picture
А это что не будет обращение к картинке или под обращением понимается запрос от нёё информации типа как .Canvas.Pixels? Хотя когда я присваиваю к динамическому созданному объекту imageN.Picture:= image1.Picture, то я же тоже обращаюсь к статике или нет? Или надо создавать объекты в не потока?
Спасибо заранее, хочется разобраться раз и на всегда!!!

Делаю так при создании формы
Код:
for I := 3 to 52 do
 begin
 ImageSrav[i]:=Timage.Create(Form1);
 ImageSrav[i].Parent:=Form1;
 ImageSrav[i].AutoSize:=true;
 ImageSrav[i].Visible:=false;
 ImageSrav[i].Picture:=TImage(Form1.FindComponent('Image'+IntToStr(i))).Picture;
 ImageSrav[i].Left:=TImage(Form1.FindComponent('Image'+IntToStr(i))).Left+200;
 ImageSrav[i].top:=TImage(Form1.FindComponent('Image'+IntToStr(i))).top;
 end;
но опять не работает((( Не расшифровывает!

Последний раз редактировалось ProDaNTe, 24.04.2013 в 10:32.
Ответить с цитированием
  #6  
Старый 24.04.2013, 10:39
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от ProDaNTe
...А это что не будет обращение к картинке или под обращением понимается запрос от нёё информации типа как .Canvas.Pixels? Хотя когда я присваиваю к динамическому созданному объекту imageN.Picture:= image1.Picture, то я же тоже обращаюсь к статике или нет? Или надо создавать объекты в не потока?
Спасибо заранее, хочется разобраться раз и на всегда!!!...
Ну тогда с самого начала о потоках.


Объявление потомка от TThread
Код:
...

type

TCapth = class(TThread)

private

   MyImage: TImage;

protected

    procedure Execute; override; // Выполняется в потоке

    procedure ShowResult; // Выводная процедура из потока
//   Если в основной поток нужно вернуть разные рисунки, то тогда
//   ShowResult задаётся с параметрами
//  procedure ShowResult(img: TImage); 


end;

...
Начало работы потока

Picture:= Picture это всёравно что a:= b, т.е. передается лишь копия изображения, его Canvas.Pixels не зависят от оригинала и делай с ним что хошь...
Код:
procedure TCapth.Execute;

begin

MyImage.Picture:= Form1.Image1{iz} .Picture;

 x:= MyImage.Width -1;
 y:= MyImage.Height-1;
...

// ну и так далее
...

end;
Из Execute всё же возможен вывод результатов, если что-то надо в основной поток программы вернуть прям во время исполнения потока, то в её тело добавляется строчка
Код:
...

Synchronize(ShowResult);

...

А вот и сама выводная процедура
Код:
...

procedure TCapth.ShowResult;

begin
...

// напр.
Form1.Image1{iz}.Picture:= MyImage.Picture;
...
end;

...
т.е. так обновиться рисунок имиджа на основной форме.

Из всего этого такое заключение - с потоками надо правильно обращаться и тогда всё будет работать.
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
ProDaNTe (24.04.2013)
  #7  
Старый 24.04.2013, 11:01
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Я не понимаю, че за проблема, взять в отдельном потоке набабахать битмап, по завершению через синхронайз махнуть, что мол все готово, забирайте.

И не использовать TImage, а использовать TBitmap (в случае с TImage это как в механический калькулятор засовывать абак).
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
ProDaNTe (24.04.2013)
  #8  
Старый 24.04.2013, 11:12
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

Цитата:
Picture:= Picture это всёравно что a:= b, т.е. передается лишь копия изображения, его Canvas.Pixels не зависят от оригинала и делай с ним что хошь...
procedure TCapth.Execute;

begin
MyImage.Picture:= Form1.Image1{iz} .Picture;
x:= MyImage.Width -1;
y:= MyImage.Height-1;
...
// ну и так далее
...
end;
Ну так я так и сделал, но не работает(((
P.S. Я знаю о работе потока, но не знаю как взаимодействовать с изображениями в потоке, при обращении к картинкам даже созданным динамически они начинают исчезать((

Цитата:
И не использовать TImage, а использовать TBitmap (в случае с TImage это как в механический калькулятор засовывать абак).
Попробую!

Последний раз редактировалось ProDaNTe, 24.04.2013 в 11:22.
Ответить с цитированием
  #9  
Старый 24.04.2013, 14:22
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

C TBitmap тоже не работает(((, Если не в потоке, а просто процедурой то все ок, а в потоке не в какую ПОЧЕМУ!!!! ИзвИните имоции...
Садись, два

Код:
...
    type
  TCapth = class(TThread)
  protected
  procedure Execute; override;
  end;

...
  ImageSrav:array [3..53] of TBitmap;

...
for I := 3 to 52 do
 begin
 ImageSrav[i]:=TBitmap.Create;
 ImageSrav[i]:=TImage(Form1.FindComponent('Image'+IntToStr(i))).Picture.Bitmap;
 end;
...


procedure TCapth.execute;
var
i,x,y,l,j,iz:integer;
s:integer;
stop:Boolean;
cap:String;
proz,posx,posy,all:Integer;
begin
  inherited;
   cap:='';
 for posx := 3 to 77 do begin
 for posy := 3 to 15 do begin
 s:=0;
 iz:=2;

 repeat
    iz:=iz+1;
    all:=0;
    s:=0;
    proz:=0;
 x:=ImageSrav[iz].Width-1;
 y:=ImageSrav[iz].Height-1;
 for l := 0 to x do begin
 for j := 0 to y do begin

if ImageSrav[iz].Canvas.Pixels[l,j]<>RGB(255,255,255) then begin
  all:=all+1;
 end;

 end;
 end;

 for l := 0 to x do begin
 for j := 0 to y do begin
if (ImageSrav[iz].Canvas.Pixels[l,j]=ImageSrav[53].Canvas.Pixels[l+posx,j+posy]) and
   (ImageSrav[iz].Canvas.Pixels[l,j]<>RGB(255,255,255)) then
begin
s:=s+1;
end;
 end;
 end;
 proz:=round(s/all*100);

  if proz>60 then begin
  case iz of
  3..7:cap:=cap+'0';
  8..12:cap:=cap+'1';
  13..17:cap:=cap+'2';
  18..22:cap:=cap+'3';
  23..27:cap:=cap+'4';
  28..32:cap:=cap+'5';
  33..37:cap:=cap+'6';
  38..42:cap:=cap+'7';
  43..47:cap:=cap+'8';
  48..52:cap:=cap+'9';
  end;
  end;

     until iz=52;
 end;
 end;

   Form1.sEdit2.Text:=cap;
end;

Последний раз редактировалось Aristarh Dark, 24.04.2013 в 15:51.
Ответить с цитированием
  #10  
Старый 24.04.2013, 15:52
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Ты бы написал что тебе нужно-то, а то сидеть и разбираться в коде который не работает, лично мне - не хочется.
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #11  
Старый 24.04.2013, 16:15
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

Цитата:
Ты бы написал что тебе нужно-то, а то сидеть и разбираться в коде который не работает, лично мне - не хочется.
Читай внимательнее он рабочий, но только когда как процедура формы, а не в потоке.
Что там разбирать взлом капчи по шаблону, всё работает если не в потоке, а в потоке отказывается.
Так как цифры имеют наклон и наложение друг на друга, то это самый работоспособный код, что у меня созрел, но как запускаю потоком все изображения на форме пропадают, хотя я их в битмапы запихнул и те что на форме в потоке не используются!!!

P.S. Заместо орфогрфии лучше бы код хоть глазком взглянул
Ответить с цитированием
  #12  
Старый 24.04.2013, 16:20
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Цитата:
Сообщение от ProDaNTe
Читай внимательнее он рабочий, но только когда как процедура формы, а не в потоке.
Что там разбирать взлом капчи по шаблону, всё работает если не в потоке, а в потоке отказывается.
Так как цифры имеют наклон и наложение друг на друга, то это самый работоспособный код, что у меня созрел, но как запускаю потоком все изображения на форме пропадают, хотя я их в битмапы запихнул и те что на форме в потоке не используются!!!

P.S. Заместо орфогрфии лучше бы код хоть глазком взглянул

Не хочу смотреть, потому что в коде даже форматирования нормального нету.
Можно же написать:
1. Есть много (сколько?) картинок и еще одна
2. Посчитали сколько не белых точек на этих много картинок
3. Потом чего-то там сравниваем с еще одной картинкой(?)
4. Что-то делаем с результатом(?)

Просто ж очень описать действия.
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #13  
Старый 24.04.2013, 16:32
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

Цитата:
Не хочу смотреть, потому что в коде даже форматирования нормального нету.
Ну если это поможет то вот:
Есть картинка капчи далее ImageSrav[53]
Далее есть 50 шаблонов картинок ImageSrav[3..52]
Запускаем цикл установки позиции 2 шт по x и y соответственно
Код:
 for posx := 3 to 77 do begin
 for posy := 3 to 15 do begin
Запускаем цикл в нутри тех 2 циклов который сравнивает шаблон с капчей,
Код:
 repeat
    iz:=iz+1;
    all:=0;
    s:=0;
    proz:=0;
 x:=ImageSrav[iz].Width-1;
 y:=ImageSrav[iz].Height-1;
а именно он считает сколько всего не белых точек all
Код:
 for l := 0 to x do begin
 for j := 0 to y do begin
 
if ImageSrav[iz].Canvas.Pixels[l,j]<>RGB(255,255,255) then begin
  all:=all+1;
 end;
 
 end;
 end;
Затем считает сколько совпадений пикселей по не белым точкам s
Код:
 for l := 0 to x do begin
 for j := 0 to y do begin
if (ImageSrav[iz].Canvas.Pixels[l,j]=ImageSrav[53].Canvas.Pixels[l+posx,j+posy]) and
   (ImageSrav[iz].Canvas.Pixels[l,j]<>RGB(255,255,255)) then
begin
s:=s+1;
end;
 end;
 end;
потом считает процент совпадения proz
Код:
 proz:=round(s/all*100);
Если больше 60 процентов то строке cap приравнивается предидущая надпись исходя из номера изображения
Код:
  if proz>60 then begin
  case iz of
  3..7:cap:=cap+'0';
  8..12:cap:=cap+'1';
  13..17:cap:=cap+'2';
  18..22:cap:=cap+'3';
  23..27:cap:=cap+'4';
  28..32:cap:=cap+'5';
  33..37:cap:=cap+'6';
  38..42:cap:=cap+'7';
  43..47:cap:=cap+'8';
  48..52:cap:=cap+'9';
  end;
  end;
Ну и в конце все это выводится в эдит!!!
Ответить с цитированием
  #14  
Старый 24.04.2013, 17:12
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

План действий примерно такой:
1. Свести к минимуму обращение к VCL компонентам (в идеале обращение только к Edit'у и уже тем более никаких TImage)
2. Прочитать 1 пункт 50 раз.
3. Не пересчитывать все время количество белых точек.
Сделать например так (упрощенно, лучше конечно класс сделать):
Код:
type
  TTemplate = record
    bitmap:TBitmap;
    whitecount:integer;
    mask:array of array of boolean;
  end;
картинки загрузить в bitmap из файлов при инициализации потока, посчитать количество белых точек записать в whitecount, установить размеры массива маски равные размеру картинки и заполнить false в координатах белых точек (это понадобится для того чтобы избавится от проверки "а не белая ли точка на шаблоне", и съэкономит время)
4. Загрузить из файла картинку с капчей (тож в TBitmap) и с ней уже производить сравнения.
5. После всего через синхронайз вывести данные на форму.
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #15  
Старый 24.04.2013, 17:31
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

Так здаесь где VCL компонент ну кроме sEdit2?
Код:
procedure TCapth.execute;
var
i,x,y,l,j,iz:integer;
s:integer;
stop:Boolean;
cap:String;
proz,posx,posy,all:Integer;
begin
inherited;
   cap:='';
 for posx := 3 to 77 do begin
 for posy := 3 to 15 do begin
 s:=0;
 iz:=2;
 
 repeat
    iz:=iz+1;
    all:=0;
    s:=0;
    proz:=0;
 x:=ImageSrav[iz].Width-1;
 y:=ImageSrav[iz].Height-1;
 for l := 0 to x do begin
 for j := 0 to y do begin
 
if ImageSrav[iz].Canvas.Pixels[l,j]<>RGB(255,255,255) then begin
  all:=all+1;
 end;
 
 end;
 end;
 
 for l := 0 to x do begin
 for j := 0 to y do begin
if (ImageSrav[iz].Canvas.Pixels[l,j]=ImageSrav[53].Canvas.Pixels[l+posx,j+posy]) and
   (ImageSrav[iz].Canvas.Pixels[l,j]<>RGB(255,255,255)) then
begin
s:=s+1;
end;
 end;
 end;
 proz:=round(s/all*100);
 
  if proz>60 then begin
  case iz of
  3..7:cap:=cap+'0';
  8..12:cap:=cap+'1';
  13..17:cap:=cap+'2';
  18..22:cap:=cap+'3';
  23..27:cap:=cap+'4';
  28..32:cap:=cap+'5';
  33..37:cap:=cap+'6';
  38..42:cap:=cap+'7';
  43..47:cap:=cap+'8';
  48..52:cap:=cap+'9';
  end;
  end;
 
     until iz=52;
 end;
 end;
 
   Form1.sEdit2.Text:=cap;
end;
Код:
картинки загрузить в bitmap из файлов при инициализации потока
А вот тут поподробнее как их загрузить при инициализации
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 01:16.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter