Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2007.04.08;
Скачать: [xml.tar.bz2];

Вниз

Функция извлечения цветов из BMP в массив   Найти похожие ветки 

 
lyberzon ©   (2006-08-02 16:43) [0]

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


 
antonn ©   (2006-08-02 17:18) [1]

отдельно RGB из TColor?
var r, b, g:byte;
begin
r:=GetRValue(trColor); g:=GetGValue(trColor); b:=GetBValue(trColor);

или

r:=Byte(trColor);
g:=Byte(trColor shr 8);
b:=Byte(trColor shr 16);


 
antonn ©   (2006-08-02 17:18) [2]

для скорости можно воспользоваться scanline() для попиксельного пробега и получения все тех же RGB


 
Cash ©   (2006-08-02 17:34) [3]

... или для получения TColor из BMP??? (мне и самму не верится, но
мога-быть и такое)

TBitMap.Pixels[x,y: integer]: TColor, мога такое.


 
Virgo_Style ©   (2006-08-02 19:49) [4]

м.б. требуется извлечь из bmp данные об использованной палитре?


 
Степан   (2006-08-02 21:00) [5]

Я кажется нашел! Тебе надо в строну функции GetPaletteEntries рыть! Она на основе дескриптора палитры (Bitmap.Palette, так в Делфи помоему) выдает массив с ее содержимом, подробнее описано в MSDN (Windows SDK) -> Colors Overview


 
Lyberzon ©   (2006-08-03 15:15) [6]

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

Теперь по существу. Мне нужно извлечь из BMP задействованные цвета в массив с тем, чтобы потом я мог по выбору заменить любой выбранный цвет в картинке на другой. А с извлечением имеющейся палитры, я думаю, связываться бесполезно, т.к. некоторые форматы BMP ее не имеют. При этом алгоритм должен быть достаточно быстрым. Простое сканирование пикселей типа TBitMap.Pixels[x,y: integer]: TColor отпадает - чрезвычайно медленно. Необходимо что-то, что работало бы побыстрей.


 
Lyberzon ©   (2006-08-03 15:22) [7]

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


 
antonn ©   (2006-08-03 15:28) [8]

Lyberzon ©   (03.08.06 15:15) [6]
Простое сканирование пикселей типа TBitMap.Pixels[x,y: integer]: TColor отпадает - чрезвычайно медленно. Необходимо что-то, что работало бы побыстрей.

[2] ?


 
lyberzon ©   (2006-08-03 15:41) [9]

Я имел ввиду сканирование пикселей и сравнение их с уже занесенными в массив (если цвет текущего пикселя уже был однажды занесен в массив, то этот осуществляется переход к следующему и т.д.)


 
Jeer ©   (2006-08-03 15:44) [10]

так и непонятно, с чем проблемы - выяснить TColor пикселя или разработка собственного алгоритма сравнения чего-то с чем-то ?


 
lyberzon ©   (2006-08-03 16:09) [11]

Итак, я загружаю BMP из файла. На специальной панели отображается палитра цветов (все те цвета, из которых и состоит изображение). Я сликаю мышкой по любому цвету на панели, открывается диалог выбора цвета. Я выбираю другой цвет, и на изображении исходный цвет меняется на выбранный. Как это реализовать без использования TBitMap.Pixels[x,y: integer] ?


 
Jeer ©   (2006-08-03 16:36) [12]

Повторю - scanline ?

А алгоритм прост до неприличия:
если цвет = искомый, то цвет := выбранный


 
lyberzon ©   (2006-08-03 16:46) [13]

Ну а как с помощью scanline? Мне бы желательно код-пример. Jeer, как думаешь, за сколько времени предлагаемая реализация просчитает цвета картинки размером 1600Х1200?


 
lyberzon ©   (2006-08-03 16:47) [14]

Прошу прощения, ...как Вы думаете...?


 
Jeer ©   (2006-08-03 17:26) [15]


> как Вы думаете.


Не суть.

Важно, чтобы ты начал думать

F1 scanline

В help-e развернутый пример.

1024x768 сканируется за 20 ms на P-IV 2 GHz


 
Lyberzon ©   (2006-08-03 17:47) [16]

Спасибо. Вечером попробую...


 
Cash ©   (2006-08-03 20:13) [17]

lyberzon:
ScanLine конечно! он тебе вернет массив линии из картинки (строки по
моему...).
А там простым проходом по элементам вытягивай цвета и смотри.

Товарищ, а у вас алгоритм быстрой проверки наличия цвета есть? Простой
перебор не решит проблему за требуемое время!


 
Lyberzon ©   (2006-08-04 10:58) [18]

Вот и я о том же. Ребят, может поможете живым примером? Буду очень благодарен.


 
Jeer ©   (2006-08-04 11:29) [19]

Расскажи лучше, чем тебя 20 ms не устраивают.


 
Lyberzon ©   (2006-08-04 11:51) [20]

Да меня и это устраивает. Просто ни кто не хочет воочию показать, как это реализовать, то-есть живым примером кода.


 
Jeer ©   (2006-08-04 11:53) [21]

Зачем ?
Справку лень читать ?
набираешь в редакторе scanline
выделяешь и нажимаешь F1
Перед тобой окажется "живой" код от Borland


 
Lyberzon ©   (2006-08-04 13:21) [22]

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


 
Jeer ©   (2006-08-04 13:44) [23]

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

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;


 
Cash ©   (2006-08-04 14:41) [24]

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

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


 
Jeer ©   (2006-08-04 15:40) [25]

Cash ©   (04.08.06 14:41) [24]

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


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

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


 
lyberzon ©   (2006-08-04 17:06) [27]

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


 
Jeer ©   (2006-08-04 17:13) [28]

lyberzon ©   (04.08.06 17:06) [27]


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


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

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


 
lyberzon ©   (2006-08-05 09:23) [29]

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

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.


 
MBo ©   (2006-08-05 14:08) [30]


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;


 
MBo ©   (2006-08-05 14:10) [31]

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


 
lyberzon ©   (2006-08-06 08:38) [32]

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


 
lyberzon ©   (2006-08-06 08:39) [33]

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


 
lyberzon ©   (2006-08-06 08:42) [34]

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


 
Lyberzon ©   (2006-08-07 10:57) [35]


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


 
Jeer ©   (2006-08-07 11:14) [36]

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 13:32) [37]

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


 
MBo ©   (2006-08-07 13:42) [38]

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


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

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

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

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

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


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

MBo ©   (07.08.06 13:42) [38]

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

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



Страницы: 1 2 вся ветка

Форум: "Media";
Текущий архив: 2007.04.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.272 c
2-1174395550
San ciz
2007-03-20 15:59
2007.04.08
Интерфейс


2-1174373951
БЫЛ
2007-03-20 09:59
2007.04.08
string в var Buf


15-1173784031
Карелин Артем
2007-03-13 14:07
2007.04.08
Отделить Газели пассажирские от других машин. Как?


15-1173640857
Cyrax
2007-03-11 22:20
2007.04.08
Активные форумы по CASE-системам...


2-1173987499
Востоковед
2007-03-15 22:38
2007.04.08
Таблица <-> Delphi - Новичок запутался...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский