Цитата:
	
	
		| 
			
				 Сообщение от alexnov 
				Доброго времени суток! 
Задача состоит в следующем: из загруженной картинки (для начала BMP) необходимо получить количество пикселов каждого цвета, которые содержит картинка. Задача простая, но как решить не знаю, с графикой дела не имел! Поможите плиз! )) 
			
		 | 
	
	
 
Очень понравилась задача, решил попробовать свои силы)
Идея проста, но сложно реализована для повышения производительности.
желательно на время работы функции блокировать вызывающий ее обработчик.
	Код:
	function TForm1.HowManyColors(const Bitmap: TBitmap; const Memo:TMemo): Integer;
type //это лучше определять в начале модуля
  TRGB = record
    B, G, R: Byte;
  end;
  ARGB = array[0..1] of TRGB; 
  PARGB = ^ARGB;
const
  CArrayLengthInc = 10000;
type //а это в функции
  TColorCnt = record
    FColor:TColor;       //Одна ячейка массива содержит цвет
    FCount:Integer;      //и его кол-во
  end;
var
  x, y, i, l, tmp:integer;
  p: PARGB;
  Colors: Array of TColorCnt;  //Массив всех найденых цветов
begin
  //Подготовимся)
  l:=CArrayLengthInc;
  SetLength(Colors,l); //для начала создадим массив на 10000 элементов
  //Функция SetLength будет тормозить весь процесс, лучше 
  //ее вызывать поменьше)
  with Colors[0] do
    begin
    FColor:=0; //один цвет (черный) определим заранее
    FCount:=0;
    end;
  Result:=1; //Result - кол-во найденных элементов)
  with Bitmap do
    for y := 0 to Height - 1 do //перебираем строки массива(линии картинки)
      begin
      p := ScanLine[y];
      for x := 0 to Width - 1 do//перебираем элементы массива (пиксели)
         begin
         with p[x] do  tmp:=(r*g*b);  //берем цвет пикселя
         for i:=0 to Result - 1 do  //перебираем цвета
             if Colors[i].FColor = tmp then // если у нас есть такой цвет
               begin
               Inc(Colors[i].FCount);  //то увеличиваем у него счетчик
               Break;    //и покидаем цикл перебора цветов
               end;
         if Length(Colors)=Result then //иначе проверяем не достигнут ли 
           begin                              //конец массива
           Inc(l,CArrayLengthInc);  //если да, то увеличиваем его еще
           SetLength(Colors, l);     //на 10000 элементов
           end;
         with Colors[Result] do //и сохраняем новый цвет
           begin
           FColor:=tmp;
           FCount:=1;
           end;
         Inc(Result);
         //результаты можно вставить вывод результата статуса
         // выполнения данной функции, к примеру если ты хочешь
         //показывать состояние выполнения)
         Application.ProcessMessages; //Это что бы приложение не висло
         end;
      end;
  
  //Вот вывести все элементы - безумие, так как цветов может быть 
  //очень большое кол-во и займет это чуть меньше времени, чем 
  //первая чать функции, я бы отказался от этой затеи)
  
  with Memo.Lines do
    begin                                   
    BeginUpdate;
    Clear;
    if (Result-Ord(Colors[0].FCount=0))>0 then
      for i:=0+Ord(Colors[0].FCount=0) to Result-1 do
        with Colors[i] do
          Add('Код цвета: '+IntToStr(FColor)+' - '+IntToStr(FCount)+' раз');
    EndUpdate;
    end;
  //пора покинуть функцию, но вдруг у картинки не было черного цвета, 
  if Colors[0].FCount = 0 then Dec(Result); // не будем врать)
  SetLength(Colors,0);  //и освободим массив
end;
procedure TForm1.MMHowManyColorsClick(Sender: TObject);
begin
  ShowMessage('Изображение содержит '+Inttostr(
    HowManyColors(Image1.Picture.Bitmap,Memo1))+' цветов');
end; 
 
При больших и многокрасочных изображениях, процесс выполнения будет длительным (в этом случае, как минимум стоит удалить вывод всех элементов, блок with Memo Lines do begin .. end)!
Удачи)