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

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

Определение цвета и преобразование палитры [D7, WinXP]


Lockdog ©   (2006-09-13 17:29:00) 

В общем идея такая:
мне нужно снять скрин, потом преобразовать палитру в 4096 цветную, а затем выделить область (например от 0 до 200 пикселей)по всей левой части экрана и найти цвет, который в этой области чаще всего встречается, кто поможет?

Заранее спасибо


Lockdog   (2006-09-14 21:22:00) [1]


> Только ответь на один вопрос:
> Как ты собираешься сохранять и показывать изображения 12-
> битовой палитрой?

МНЕ НЕ НАДО ЕЁ СОХРАНЯТЬ, ТАМ ДРУГОЕ ДЕЛО


han_malign   (2006-09-14 18:09:00) [2]

Если нужна адаптивная палитра цветов, то есть готовый "Gervautz-Purgathofer Octree Color Quantization" алгоритм
http://homepages.borland.com/efg2lab/Graphics/Colors/ShowDemoOne.htm
(портирован на Delphi с http://www.microsoft.com/msj/1097/wicked1097.aspx)


SamBrook   (2006-09-14 17:05:00) [3]


> Lockdog   (14.09.06 15:52) [9]
> Так что же лучше?

Да как хочешь так и делай.
Способ Vovan проще в реализации, но качество может быть хуже.
Только не делай простого перебора - использует tBucketlist с цветом в качестве индекса pointer(tcolor).

Только ответь на один вопрос:
Как ты собираешься сохранять и показывать изображения 12-битовой палитрой?


Lockdog   (2006-09-14 15:52:00) [4]

Так что же лучше?


SamBrook   (2006-09-13 23:56:00) [5]

Vovan#1   (13.09.06 21:19) [5]

Метод медианного сечения - это способ создания оптимальной 256-цветной палитры для многоцветных изображений.

В задаче Lockdog палитра же 4096 цветную. Такому изображению палитра не нужна.


Метод медианного сечения может применяться для любой палитры, число отсчетов которой = 2^k.

У автора снимок экрана - обычно 24(32) бит/пиксел которые нужно перевести в 12.

Размер, кстати, может быть нехилым при большом разрешении экрана

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


Vovan#1   (2006-09-13 22:28:00) [6]

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

Сперва измерь скоростные характеристики, устраивают ли они тебя. Если нет - попробуй оптимизировать. Используется Scanline - это уже задел. Можно перевести в 32-бита и будет чуточку быстрее. У сканлайна есть и свои способы ускорения. Объект TList каждый раз создаётся - это потеря времени. Создай его раз и очищай потом. И сортировочку на побыстрее заменить. И будет тебе счастье.


Lockdog   (2006-09-13 21:39:00) [7]


> Создать частотную характеристику для каждого используемого
> цвета во всём изображении. Я делал это так (картинка была
> маленькая, память и процессорное время не берёг):

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


Vovan#1   (2006-09-13 21:19:00) [8]

Метод медианного сечения - это способ создания оптимальной 256-цветной палитры для многоцветных изображений.

В задаче Lockdog палитра же 4096 цветную. Такому изображению палитра не нужна. Если задача стоит в понижении количества цветов до 4096, то предлагаю такой простой способ:

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


 PColorFreq = ^TColorFreq;
 TColorFreq = record
  Color: TColor;
  Freq: Integer;
 end;

function CreateColorFreqList(B: TBitmap): TList;
var
 x, y, i: Integer;
 Row: PRGBTripleArray;
 F: Boolean;
 CItem, CItem2: PColorFreq;
 C: TColor;
begin
 Result := TList.Create;
 If B.PixelFormat <> pf24bit then Exit;
 for y := 0 to B.Height-1 do
  begin
   Row := B.Scanline[y];
   for x := 0 to B.Width-1 do
    begin
     with Row[x] do
      C := RGB(rgbtRed, rgbtGreen, rgbtBlue);
     F := False;
     for i := 0 to Result.Count-1 do
      begin
       CItem := Result.Items[i];
       If CItem.Color = C then
        begin
         Inc(Citem.Freq);
         F := True;
         Break;
        end;
      end;
      If F = False then
       begin
        New(CItem);
        CItem.Color := C;
        CItem.Freq := 1;
        Result.Add(CItem);
       end;
    end;
   end;
 // sorting
 for y := 0 to Result.Count-1 do
    begin
     for x := y+1 to Result.Count-1 do
      begin
       CItem := Result.Items[y];
       CItem2 := Result.Items[x];
       If CItem2^.Freq > CItem^.Freq then
        Result.Exchange(x, y);
      end;
    end;
end;


В отсортированном по убыванию списке выбрать первые 4096 цветов и к ним приравнивать остальные.

Ну а если сделано это, то "выделить область (например от 0 до 200 пикселей)по всей левой части экрана и найти цвет, который в этой области чаще всего встречается" тем же способом не составит труда.


Lockdog   (2006-09-13 21:01:00) [9]

И что это?


SamBrook   (2006-09-13 18:49:00) [10]

STFW "Метод медианного сечения".


Lockdog   (2006-09-13 17:34:00) [11]

Как мне это сделать?:)


Eraser   (2006-09-13 17:31:00) [12]

> [0] Lockdog   (13.09.06 17:29)

а в чем проблемы?


Наверх

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