Форум: "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.036 c