Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Функция извлечения цветов из BMP в массив [D7, WinXP]


Страницы:   1 2 3

lyberzon ©   (2006-08-02 16:43:00) 

Привет всем!!! Ребят, подскажите плз., функцию извлечения цветовой палитры из картинки в массив, например, из элементов ТColor. Нигде не могу найти такого. Может плохо искал?


Jeer   (2006-08-07 16:16:00) [1]

lyberzon ©   (06.08.06 08:42) [34]

Как минимум:

          if (R<>Colors[i].R) or
            (G<>Colors[i].G) or
            (B<>Colors[i].B) then
          begin
           inc(nColors);
           SetLength(Colors,nColors);
           Colors[nColors-1].R:=R;
           Colors[nColors-1].G:=G;
           Colors[nColors-1].B:=B;
            break
          end;

иначе бесконечный цикл.


Jeer   (2006-08-07 16:00:00) [2]

MBo ©   (07.08.06 13:42) [38]

Да, что-то меня смущало:))

Разумеется arRGB[0..255, 0..255, 0..255] of boolean
вместо трех массивов.


Cash   (2006-08-07 14:39:00) [3]

(просю прощения за отсутствие в дискуссии.)

А я не зря про деревья спрашивал, проблему такую я не решал, но подумал,
что с помощью структуры СДП (Случайное Дерево Поиска) время решения
этой проблемы может сократиться до приемлемых значений. Трудоемкость
поиска по СДП соответствует глубине этого дерева. Конечно с СДП есть
реальная вероятность вырождения его в список, но для данного случая,
я думаю, это мало вероятно.

Суть метода в том, чтобы добавлять в вершины дерева сами цвета (TColor),
слева меньший цвет, справа -- больший. При добавлении нового элемента
поиск его совпадений производится автоматически, т. к. мы в любом случае
должны сравнить добавляемый элемент с тем, который находится в текущей
вершине дерева. Если значение вершины совпадает с добавляемым, то
просто выходим без добавлений.

Формировать палитру можно как при проходе, так и при заполнении дерева.


MBo   (2006-08-07 13:42:00) [4]

>Jeer ©   (07.08.06 11:14) [36]
после обработки трех точек с цветами
0,0,0
1,1,1
2,2,2
цвет 0,1,2 будет считаться уже имеющимся, а это не так...


Lyberzon   (2006-08-07 13:32:00) [5]

Решение довольно таки мудрое, уважаемый Jeer. Я так и поступлю. Мне только одно интересно, где я допустил ошибку в своем коде (см. выше)? Просто интересно...


Jeer   (2006-08-07 11:14:00) [6]

lyberzon ©   (06.08.06 08:42) [34]

Вариант 1.

Для фиксации цветов можно поступить так:
Завести три массива, где индекс определяется значением соответствующей цветовой составляющей:

 arR, arG, arB: array [0..255] of boolean;

Тогда фиксация наличия цвета сводится к:
arR[R] := True;
arG[G] := True;
arB[B] := True;

где R,G,B - найденные цветовые составляющие ij-пикселя

Определение числа цветов в палитре сведется к просчету числа True в каждом массиве Nr, Ng, Nb и получению Ncolors := Nr*Ng*Nb

Или, как вариант,
if not(arR[R] and arG[G] and arB[B]) then Inc(Ncolors);
и после
arR[R] := True;
arG[G] := True;
arB[B] := True;

Затем получение массива arColors: TColor :

SetLength(arColors, Ncolors);
Вложенное сканирование всех трех массивов arR,arG,arB

if (arR[i] and arG[j] and arB[k]) then begin
 arColors[m] := TColor((i shl 16) or (j shl 8) or k);
 Inc(m)
end;


Lyberzon   (2006-08-07 10:57:00) [7]


> И насчет моего кодинга. Неужели никто не может исправить
> мою ошибку, или хотя бы указать на нее. Народ, очень нужно!
>


lyberzon   (2006-08-06 08:42:00) [8]

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


lyberzon   (2006-08-06 08:39:00) [9]

Хочу заметить, что цвета в массиве не должны повторяться.


lyberzon   (2006-08-06 08:38:00) [10]

А как с помощью TQuickPixelsизвлеч имеющиеся в BMP цвета и поместить их в массив, с целью дальнейшего заполнения таблицы (палитры) из этого массива? Желательно использование динамического массива из элементов TColor. Уважаемый MBo, подскажите пожалуйста.


MBo   (2006-08-05 14:10:00) [11]

в конце функции, конечно, еще
 qp.Free;
 Bits.Free;


MBo   (2006-08-05 14:08:00) [12]


uses UQPixels;
// http://www.delphimaster.ru/articles/pixels/index.html

function GetColorCount(const PicName: string): Integer;
var
 x, y: Integer;
 c: Integer;
 qp: TQuickPixels;
 b: TBitmap;
 Bits: TBits;
begin
 Result := 0;
 b := TBitmap.Create;
 b.LoadFromFile(PicName);
 qp := TQuickPixels.Create;
 qp.Attach(b);
 Bits := TBits.Create;
 Bits.Size := $1000000;
 for y := 0 to b.Height - 1 do
   for x := 0 to b.Width - 1 do begin
     c := $FFFFFF and qp.Pixels[x, y];
     if not Bits[c] then begin
       Inc(Result);
       Bits[c] := True;
     end;
   end;
 b.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Caption := IntToStr(GetColorCount('test.bmp'));
end;


lyberzon   (2006-08-05 09:23:00) [13]

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

unit Main;

interface

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

type
 TMainForm = class(TForm)
   PaintBox1: TPaintBox;
   MainMenu1: TMainMenu;
   File1: TMenuItem;
   Opensprite1: TMenuItem;
   OpenDialog1: TOpenDialog;
   procedure FormCreate(Sender: TObject);
   procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
 private

 public
   { Public declarations }
 end;

var
 MainForm: TMainForm;
 Bitmap: TBitmap;

implementation

{$R *.dfm}

type
TRGB=record
 B,G,R: Byte;
end;
pRGB = ^TRGB;
TDynArray = array of TRGB;

var
Colors: TDynArray;

function CalculateColors(Bitmap: TBitmap): Integer;
var
i,x,y,nColors: Integer;
Dest: pRGB;

begin
Bitmap.PixelFormat:=pf24bit;
nColors:=0;
for y:=0 to Bitmap.Height-1 do
 begin
  Dest:=Bitmap.ScanLine[y];
  for x:=0 to Bitmap.Width-1 do
   begin
    with Dest^ do
     begin
      if Colors<>nil then
       begin
        for i:=0 to nColors-1 do
         begin
          if (R<>Colors[i].R) or
             (G<>Colors[i].G) or
             (B<>Colors[i].B) then
           begin
            inc(nColors);
            SetLength(Colors,nColors);
            Colors[nColors-1].R:=R;
            Colors[nColors-1].G:=G;
            Colors[nColors-1].B:=B;
           end;
         end;
       end
      else
       begin
        nColors:=1;
        SetLength(Colors,nColors);
        Colors[nColors-1].R:=R;
        Colors[nColors-1].G:=G;
        Colors[nColors-1].B:=B;
       end;
     end;
    Inc(Dest);
   end;
 end;
Result:=nColors;
end;

procedure TMainForm.Opensprite1Click(Sender: TObject);
begin
if (OpenDialog1.Execute) then
 begin
  Bitmap.LoadFromFile(OpenDialog1.FileName);
  PaintBox1.Canvas.Draw(0,0,Bitmap);
  ShowMessage(IntToStr(CalculateColors(Bitmap)));
 end;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
Bitmap:=TBitmap.Create;
end;

procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
Bitmap.Free;
end;

end.


Jeer   (2006-08-04 17:13:00) [14]

lyberzon ©   (04.08.06 17:06) [27]


> тебе готовы помочь абсолютно незнакомые люди.


А тут так - и помочь и навредить тебе всегда способны апсолютно незнакомые люди.

Но, если чего - заходи.
С "расцветкой" всегда поможем:))


lyberzon   (2006-08-04 17:06:00) [15]

Ну знания мои не настоль обширны, на сколько хотелось бы. Но написать игрушку типа "Сокобан" на DelphiX мне по силам. В базах данных - абсолютный 0. И вообще, я еще учусь и многого не знаю, поэтому и обращаюсь за помощью. Прошу не судить меня строго, а за помощь огромное спасибо. Приятно осознавать, что в случае необходимости, тебе готовы помочь абсолютно незнакомые люди. Спасибо, ребята!


Cash   (2006-08-04 16:31:00) [16]

Jeer ©   (04.08.06 15:40) [25]:
Да не в сканлайне дело, чел хочет поведать таинство определенного
алгоритма, который не освещен в справке вааще.


Jeer   (2006-08-04 15:40:00) [17]

Cash ©   (04.08.06 14:41) [24]

В данном случае, скорее всего, надо начинать с простых вещей.
Если scanline вызвал такие затруднения, то... начинаем с понимания, что есть массив и какие они бывают.
А в лес (trees) он всегда успеет попасть.:))


Cash   (2006-08-04 14:41:00) [18]

Lyberzon ©   (04.08.06 13:21) [22]:
Позвольте пожалуйста поинтересоваться вашими знаниями в области
программирования (нет, это не глум, это действительно нужно для
определения того момента, с которого надо начинать эту феню).

Мне просто интересно понимание методов хранения и представления
информации, а так же знание алгоритмов и структур обработки данных.
(в частности деревья строить умеешь?)


Jeer   (2006-08-04 13:44:00) [19]

Если поможет - видимо не хочешь начать думать.

type
 TRGB = record
   b, g, r: byte;
 end;
 ARGB = array[0..1] of TRGB;
 PARGB = ^ARGB;

p: PARGB;
bmp: TBitmap;

//
// ri,gi,bi - искомый цвет
// rz,gz,bz - перезаписываемый цвет

 for y := 0 to bmp.height - 1 do
 begin
   p := bmp.scanline[y];
   for x := 0 to bmp.width - 1 do
   begin
     if (p[x].r = ri) and (p[x].g = gi) and (p[x].b = bi) then
       begin
         p[x].r  := rz;
         p[x].g := gz;
         p[x].b := bz;
       end;
   end;
 end;


Lyberzon   (2006-08-04 13:21:00) [20]

Да, а как конкретно реализовать сравнение сосканированого цвета с цветами в массиве, и в каком виде они будут храниться в массиве? Или в каком виде удобней их хранить? И массив, подозреваю, должен быть "резиновым". Вот где загвоздка. А со сканированием мне ясно. Уважаемый Jeer, ну дайте хоть кусочек кода! :)))


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо