Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 725

/ вопрос открыт /

Доброго времени суток, уважаемые эксперты! Буду очень признателен за помощь. Имеется матрица a[i,j], в которой содержатся цвета пикселей. Необходимо вывести эти пиксели на канву. (Image.Canvas.Pixels[i,j]:=a[i,j]). Но при этом нужно, чтобы пользователь мог видеть, как каждый пиксель прорисовывается на канве. Как это можно сделать?

Зайцев Валентин Николаевич Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Зайцев Валентин Николаевич (статус: Посетитель)
Вопрос отправлен: 7 ноября 2011, 15:52
Состояние вопроса: открыт, ответов: 3.

Ответ #1. Отвечает эксперт: VKHacker

Здравствуйте, Зайцев Валентин Николаевич!
Выполняйте код в потоке.

Для справки:
http://www.interface.ru/home.asp?artId=6105

Ответ отправил: VKHacker (статус: 1-ый класс)
Время отправки: 7 ноября 2011, 16:26

Ответ #2. Отвечает эксперт: Вадим К

Здравствуйте, Зайцев Валентин Николаевич!
Хороший ответ звучит так - Canvas+Thread.
Для начала читаем две статьи http://www.drbob42.com/uk-bug/hood-04.htm и http://www.delphisources.ru/pages/faq/base/threads_example.html
План действий будет где то такой
Идем в File-new... и там ищем thread.
Предложит ввести имя треда, введем к примеру "MyDrawThread".
в public части добавим

a:array[0..99,0..99] of TColor; // тут размерности правильные пропишите.
в private часть добавим четыре поля
x:integer;
y:integer;
cur:TColor;
im:TCanvas;
Теперь добавляем метод, который будет отрисовывать пиксель.
в private часть добавляем
procedure drawpixel;
и жмем Ctrl+Shift+C
делфи сгенерит тело метода, куда вписывам код прорисовки пикселя.
im.pixels[x,y] := cur;

теперь переходим к методу execute, который уже будет сгенерирован
var i, j:integer;
begin
for i:=0 to 99 do begin // тут нужные размеры подставляем, вполне подойдет im.height-1 и im.width-1
  for j := 0 to 99 do begin
    cur := a[i,j];
    x := i;
    y := j;
    // эти пляски с переменными нужны, так как метод Synchronize требует метода без параметров.
    Synchronize(drawpixel);
    sleep(50); // пауза между отрисовками. Нужно медленее - вставляем больше. 1000 - это одна секунда.
  end;
end;
end;

И осталось самое последнее - запустить код. Пусть это будет по нажатию кнопки

var  t:TMyDrawThread;
begin
  t := TMyDrawThread.create(true); // true - что бы поток не стартовал сразу
  t.im := Image1.canvas; //где рисовать
  // переносим массив пикселей
  for i:= 0 to 99 do
    for j := 0 to 99 do
      t.a[i,j] := a[i,j];
  t.freeonterminate := true; // что бы поток сам себя почистил по завершению.
  t.resume; //запускаем поток.
end;

В принципе, должно запустится.
Что доделать
- передавать правильный размер массива
- подумать о правильном копировании массива или использовать указатель (но тогда может быть проблема с тем, что массив поменялся, пока отрисовывался)
если будет копироваться медленно, то можно копировать пиксели пачками (то есть вызывать sleep раз в несколько отрисовок, например так (вместо строки sleep(50);)
  if j mod 10 = 0 then sleep(50);
И будет пауза только раз на десять пикселей.
- подумать о том, что пауза может быть динамической (для более изощренного рисования)

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 7 ноября 2011, 16:32
Оценка за ответ: 5

Ответ #3. Отвечает эксперт: ierihon1

Здравствуйте, Зайцев Валентин Николаевич!
Вот это самое простое решение но с потоками конечно лучше.

var i,j:integer;
 
procedure TForm14.FormCreate(Sender: TObject);
begin
  i:=0;
  j:=0;
end;
 
procedure TForm14.tmr1Timer(Sender: TObject);
begin
  if j = 500 then
  begin
    j:=0;
    inc(i)
  end;
  Image2.Canvas.Pixels[i,j]:=mas_pix[i,j]
  if (i = 500) and (j = 500) then
    timer1.Enabled:=False;
  j:=j+1;
end;

Ответ отправил: ierihon1 (статус: 1-ый класс)
Время отправки: 7 ноября 2011, 16:36
Оценка за ответ: 5


Мини-форум вопроса

Всего сообщений: 7; последнее сообщение — 7 ноября 2011, 16:47; участников в обсуждении: 4.
min@y™

min@y™ (статус: Доктор наук), 7 ноября 2011, 16:04 [#1]:

Ну дык, по таймеру, наверное. Или как по-другому интерпретировать слова

Цитата (Зайцев Валентин Николаевич):

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

?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Зайцев Валентин Николаевич

Зайцев Валентин Николаевич (статус: Посетитель), 7 ноября 2011, 16:15 [#2]:

вот такой код должен быть в процедуре ontimer:
for i:=1 to 500 do
for j:=1 to 500 do

Image2.Canvas.Pixels[i,j]:=mas_pix[i,j]?
не получается(
ierihon1

ierihon1 (статус: 1-ый класс), 7 ноября 2011, 16:20 [#3]:

так получается что он каждый раз полностью перерисовывает всё изображение.
Зайцев Валентин Николаевич

Зайцев Валентин Николаевич (статус: Посетитель), 7 ноября 2011, 16:24 [#4]:

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

VKHacker (статус: 1-ый класс), 7 ноября 2011, 16:28 [#5]:

Здравствуйте, Зайцев Валентин Николаевич!
Выполняйте код в потоке.

Для справки:
http://www.interface.ru/home.asp?artId=6105
Зайцев Валентин Николаевич

Зайцев Валентин Николаевич (статус: Посетитель), 7 ноября 2011, 16:47 [#6]:

Спасибо, Вы мне очень помогли)
min@y™

min@y™ (статус: Доктор наук), 7 ноября 2011, 16:47 [#7]:

Цитата (Зайцев Валентин Николаевич):

вот такой код должен быть в процедуре ontimer: for i:=1 to 500 do for j:=1 to 500 do

Image2.Canvas.Pixels[i,j]:=mas_pix[i,j]? не получается(

Конечно. Надо на OnTimer отрисовывать 1 (АДЫН) пиксел, а не 250000.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!

7 ноября 2011, 21:36: Вопрос перемещён из тематического раздела Delphi » Общие вопросы по программированию в раздел Delphi » Графика (2D и 3D) в приложениях модератором Ерёмин А.А.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:25
Выполнено за 0.04 сек.