Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> хитрый цикл, работает как хочет 
:(
    Опции темы
Racer
Дата 17.8.2010, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 149
Регистрация: 28.6.2009

Репутация: нет
Всего: нет



Добрый день. у меня есть тут 1 код. 
Код

var
  Form7: TForm7;

  rc, gc, bc: array of Byte;

implementation

{$R *.dfm}

function R(Col:TColor):Byte;
var
  Color: Longint;
begin
  Color := ColorToRGB(Col);
  Result:= Color;
end;

function G(Col:TColor):Byte;
var
  Color: Longint;
begin
  Color := ColorToRGB(Col);
  Result:= Color shr 8;
end;

function B(Col:TColor):Byte;
var
  Color: Longint;
begin
  Color := ColorToRGB(Col);
  Result:= Color shr 16;
end;

procedure TForm7.Button1Click(Sender: TObject);
var
  len: integer;
  startx, stopx, starty, stopy: Integer;
  i,j, k: Integer;
  s, s2, s3: int64;
  Rav, Gav, Bav: Integer;
begin
  startx:=1;
  stopx:= 20;
  starty:=1;
  stopy:= Image1.Height-30;


  len:= (stopx-startx) * (stopy-starty);
//  ShowMessage(IntToStr(len));
  SetLength(rc, 0);
  SetLength(gc, 0);
  SetLength(bc, 0);
  SetLength(rc, len+1);
  SetLength(gc, len+1);
  SetLength(bc, len+1);

  k:= 0;
  for i := 0 to (stopx-startx) do
    for j := 0 to (stopy-starty) do begin
      rc[k]:= R(GetPixel(Image1.Canvas.Handle, i, j));
      bc[k]:= B(GetPixel(Image1.Canvas.Handle, i, j));
      gc[k]:= G(GetPixel(Image1.Canvas.Handle, i, j));
      k:= k+1;
    end;

  try
    s:= 0;
    s2:= 0;
    s3:= 0;
    for i := 0 to Length(rc)-1 do
      s:= s+ rc[i];
    Rav:= Round(s/Length(rc));
    for i := 0 to Length(gc)-1 do
      s2:= s2+ gc[i];
    Gav:= Round(s2/Length(gc));
    for i := 0 to Length(bc)-1 do
      s3:= s3+ bc[i];
    Bav:= Round(s3/Length(bc));
  except

  end;

  ShowMessage(IntToStr(Rav)+ ' '+ IntToStr(Gav)+' '+IntToStr(Bav));
end;

procedure TForm7.Button2Click(Sender: TObject);
begin
  Image1.Canvas.Brush.Color:= RGB(Random(254), Random(254), Random(254));
  Image1.Canvas.Rectangle(0, 0, Round(Image1.Width), Round(Image1.Height/2));
  Image1.Canvas.Brush.Color:= RGB(Random(254), Random(254), Random(254));
  Image1.Canvas.Rectangle(0, Round(Image1.Height/2),
    Image1.Width, Image1.Height);
end;


вот такой. проблема: когда жму кнопку 1 иногда (в 30-40% случаев нажатия) выбрасывается AV. ИДЕ тыкает сюда       s2:= s2+ пc[i]; а иногда сюда.       s3:= s3+ bc[i]; не пойму в чем дело. оно то работает  то  нет. помогите пожалуйста
PM MAIL   Вверх
Frees
Дата 17.8.2010, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 9
Всего: 54



Код

rc, gc, bc: array of Byte;
 - сделай членами класса для начала


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
Frees
Дата 17.8.2010, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 9
Всего: 54



Цитата(Racer @  17.8.2010,  20:33 Найти цитируемый пост)
len+1

не может принять значение 0?




--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
Racer
Дата 17.8.2010, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 149
Регистрация: 28.6.2009

Репутация: нет
Всего: нет



А зачем делать их членами класса?

нулем быть не может, т.к.
Код

  startx:=1;
  stopx:= 20;
  starty:=1;
  stopy:= Image1.Height-30;
  len:= (stopx-startx) * (stopy-starty);

PM MAIL   Вверх
БелАмор
Дата 17.8.2010, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: 5
Всего: 17



Цитата(Racer @  17.8.2010,  17:33 Найти цитируемый пост)
проблема: когда жму кнопку 1 иногда (в 30-40% случаев нажатия) выбрасывается AV


Вы неправильно определяете размер массива:
Цитата(Racer @  17.8.2010,  17:33 Найти цитируемый пост)

  startx:=1;
  stopx:= 20;
  starty:=1;
  stopy:= Image1.Height-30;
  len:= (stopx-startx) * (stopy-starty);

Исправьте последнюю строчку на:
Код

  len:= (stopx-startx+1) * (stopy-starty+1);

Дополнительные замечания

1. Во время отладки всегда включайте опции Range Checking и Overflow Checking. Это поможет избежать кучи проблем.
2. В функциях R, G, B вы присваиваете байту значение Longint. Это некрасиво, кроме того, при включенной опции Overflow Checking вы сразу же получите исключение.
Кстати, возможно, вас заинтересует статья: Получение составляющих TColor
3.
Цитата(Racer @  17.8.2010,  17:33 Найти цитируемый пост)
  SetLength(rc, 0);
  SetLength(gc, 0);
  SetLength(bc, 0);
  SetLength(rc, len+1);
  SetLength(gc, len+1);
  SetLength(bc, len+1);

Три первые строчки - лишние...
4.
Цитата(Racer @  17.8.2010,  19:05 Найти цитируемый пост)
А зачем делать их членами класса?

Для порядка. Допустим (теоретически), что у вас существует два экземпляра этой формы одновременно... И что будет? Посмотрите ссылку (поиск по слову "Самоделкин"): 
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=68068


Это сообщение отредактировал(а) БелАмор - 17.8.2010, 23:54
PM   Вверх
БелАмор
Дата 18.8.2010, 05:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: 5
Всего: 17



Ещё немного об оптимизации и хороших манерах...
Чтобы слишком сильно не занудствовать, я немного обработал ваш код напильником для примера...
Код

unit Unit7;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm7 = class(TForm)
    Button1: TButton;                                
    Button2: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    rc, gc, bc: array of Byte;
    procedure SomeCounts;
    procedure RandomDraw;
  public
    { Public declarations }
  end;

  // Эти два типа взяты из статьи
  TRGBS = packed record
    Red, Green, Blue, System: Byte;
  end;

  TRgbsColor = record case Boolean of
    True : (Color: TColor);
    False: (RGBS : TRGBS );
  end;

var
  Form7: TForm7;

implementation

{$R *.dfm}

procedure TForm7.Button1Click(Sender: TObject);
begin
  SomeCounts;
end;

procedure TForm7.Button2Click(Sender: TObject);
begin
  RandomDraw;
end;

procedure TForm7.SomeCounts;
var
  len: integer;
  startx, stopx, starty, stopy: Integer;
  i,j, k: Integer;
  s, s2, s3: int64;
  Rav, Gav, Bav: Integer;
  RgbsColor: TRgbsColor;
begin
  startx:=1;
  stopx:= 20;
  starty:=1;
  stopy:= Image1.Height-30;

  len:= (stopx-startx+1) * (stopy-starty+1);
  SetLength(rc, len);
  SetLength(gc, len);
  SetLength(bc, len);

  k:= 0;
  for i := 0 to (stopx-startx) do
    for j := 0 to (stopy-starty) do begin
      RgbsColor.Color := GetPixel(Image1.Canvas.Handle, i, j);
      rc[k]:= RgbsColor.RGBS.Red;
      bc[k]:= RgbsColor.RGBS.Blue;
      gc[k]:= RgbsColor.RGBS.Green;
      k:= k+1;
    end;

  try
    s:= 0;
    s2:= 0;
    s3:= 0;
    for i := Low(rc) to High(rc) do
      s:= s+ rc[i];
    Rav:= Round(s/Length(rc));
    for i := Low(gc) to High(gc) do
      s2:= s2+ gc[i];
    Gav:= Round(s2/Length(gc));
    for i := Low(bc) to High(bc) do
      s3:= s3+ bc[i];
    Bav:= Round(s3/Length(bc));
  except

  end;

  ShowMessage(IntToStr(Rav)+ ' '+ IntToStr(Gav)+' '+IntToStr(Bav));
end;

procedure TForm7.RandomDraw;
begin
  Image1.Canvas.Brush.Color:= RGB(Random(254), Random(254), Random(254));
  Image1.Canvas.Rectangle(0, 0, Round(Image1.Width), Round(Image1.Height/2));
  Image1.Canvas.Brush.Color:= RGB(Random(254), Random(254), Random(254));
  Image1.Canvas.Rectangle(0, Round(Image1.Height/2),
  Image1.Width, Image1.Height);
end;

end.

PM   Вверх
БелАмор
Дата 18.8.2010, 09:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: 5
Всего: 17



Ну вот, заикнулся об оптимизации, а сам такое напиасал...
Если обработка ограничивается тем, что приведено в исходном коде (в чём я лично сомневаюсь), то всё можно ещё упростить:
Код

unit Unit7;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm7 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    procedure SomeCounts;
    procedure RandomDraw;
  public
    { Public declarations }
  end;

  // Эти два типа взяты из статьи
  TRGBS = packed record
    Red, Green, Blue, System: Byte;
  end;

  TRgbsColor = record case Boolean of
    True : (Color: TColor);
    False: (RGBS : TRGBS );
  end;

var
  Form7: TForm7;

implementation

{$R *.dfm}

procedure TForm7.Button1Click(Sender: TObject);
begin
  SomeCounts;
end;

procedure TForm7.Button2Click(Sender: TObject);
begin
  RandomDraw;
end;

procedure TForm7.SomeCounts;
var
  len: integer;
  startx, stopx, starty, stopy: Integer;
  i, j: Integer;
  s, s2, s3: int64;
  Rav, Gav, Bav: Integer;
  RgbsColor: TRgbsColor;
begin
  startx:=1;
  stopx:= 20;
  starty:=1;
  stopy:= Image1.Height-30;

  len:= (stopx-startx+1) * (stopy-starty+1);

  s:= 0;
  s2:= 0;
  s3:= 0;
  for i := 0 to (stopx-startx) do
    for j := 0 to (stopy-starty) do begin
      RgbsColor.Color := GetPixel(Image1.Canvas.Handle, i, j);
      s:= s + RgbsColor.RGBS.Red;
      s2:= s2 + RgbsColor.RGBS.Green;
      s3:= s3 + RgbsColor.RGBS.Blue;
    end;

  Rav:= Round(s/len);
  Gav:= Round(s2/len);
  Bav:= Round(s3/len);

  ShowMessage(Format('%d %d %d', [Rav, Gav, Bav]));
end;

procedure TForm7.RandomDraw;
begin
  Image1.Canvas.Brush.Color:= RGB(Random(254), Random(254), Random(254));
  Image1.Canvas.Rectangle(0, 0, Round(Image1.Width), Round(Image1.Height/2));
  Image1.Canvas.Brush.Color:= RGB(Random(254), Random(254), Random(254));
  Image1.Canvas.Rectangle(0, Round(Image1.Height/2),
  Image1.Width, Image1.Height);
end;

end.

PM   Вверх
Racer
Дата 18.8.2010, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 149
Регистрация: 28.6.2009

Репутация: нет
Всего: нет



Спасибо огромное вам. сейчас попробую переделать
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0488 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.