Форум: "WinAPI";
Текущий архив: 2002.10.21;
Скачать: [xml.tar.bz2];
ВнизColor Mapping Найти похожие ветки
← →
SPeller (2002-09-04 04:42) [0]Всем доброго времени суток! Подскажите пожалуйста алгоритм быстрой замены одного цвета в битмапе другим. Я делал подобное, как мне позже сказали, наиотстойнейшим способом - перебирал каждый пиксель битмапа и если его цвет был Color1 то устанавливал его в Color2. Имеется хэндл загруженного изображения и нужно поменять цвет Color1 на Color2. Если кто ещё и пример тут напишет, то я вообще просто счастлив буду :-))
← →
MBo (2002-09-04 06:22) [1]считать GetDIBits, поменять цвета в полученном массиве,
SetDIBits.
при использовании этих функций надо не забыть правильно заполнить структуру tbitmapinfo
← →
SPeller (2002-09-05 06:01) [2]Загрузить то я загрузил, а вот как правильно пройтись по битовым полям и сравнивать с 32-разряжным цветом я пока не доехал. Может быть кто-нибудь подскажет ???
← →
MBo (2002-09-05 06:44) [3]TRGBQArray=array of TRGBQuad;
...
FA:TRGBQArray;
...
GetDIBits(Value.Canvas.Handle,Value.Handle,0,FHeight,FA,FInfo,DIB_RGB_COLORS);
...
В динамическом массиве FA у меня лежат теперь точки
function GetPixels(X, Y: Integer): TColor;
var i:integer;
begin
i:=integer(FA[(FHeight-y-1)*FWidth+x]);
Result:=(i and $ff00) or (i and $ff shl 16) or (i and $ff0000 shr 16);
end;
procedure SetPixels(X, Y: Integer; const Value: TColor);
var col:cardinal;
begin
asm
mov eax,Value
bswap eax
shr eax,8
mov col,eax
end;
FA[(FHeight-y-1)*FWidth+x]:=TRGBQuad(Col);
end;
Тебе получение цвета в конкретной точке (FA[(FHeight-y-1)*FWidth+x)], видимо, не нужно, достаточно просто привести искомый цвет к TRGBQuad и пробежать по массиву
← →
SPeller (2002-09-06 02:43) [4]Большое спасибо. Я в принципе сделал уже но ужаснейшим способом:
(пишу замену апи-функции CreateMappedBitmap, которая может работать с 24-битными битмапами)
function _CreateMappedBitmap(Instance: THandle; Bitmap: Integer; Flags: Cardinal; ColorMap: PColorMap; NumMaps: Integer): HBitmap;
var bi: TBITMAPINFO; bm: Windows.TBITMAP; tmcl, curcl, DC, bpsc: cardinal;
Bits: array of byte; i,j,k: integer; CM: PColorMap;
CO: cardinal; tm:array[1..4]of byte;
begin
Result:=LoadBitmap(Instance, PChar(int2str(Bitmap)) );
if Result = 0 then exit;
DC:=CreateCompatibleDC(0);
FillChar( bm, SizeOf(bm), 0 );
GetObject( Result, SizeOf(bm), @bm );
FillChar( bi, SizeOf(bi), 0 );
bi.bmiHeader.biSize:=SizeOf(bi.bmiHeader);
bi.bmiHeader.biWidth:=bm.bmWidth;
bi.bmiHeader.biHeight:=bm.bmHeight;
bi.bmiHeader.biPlanes:=1;
bi.bmiHeader.biBitCount:=24;//bm.bmBitsPixel;
bi.bmiHeader.biCompression:=BI_RGB;
bpsc:=(bm.bmWidth*3+3) and $FFFFFFFC; //bytes per scan line
SetLength( Bits, bpsc*bm.bmHeight );
GetDIBits( DC, Result, 1, bm.bmHeight, @Bits[0], bi, DIB_RGB_COLORS );
for i:=0 to bm.bmHeight-1 do begin
for j:=0 to bm.bmWidth-1 do begin
CO:=bpsc*i + BytesPPixel*j;
for k:=0 to NumMaps-1 do begin
CM:= IncPt( ColorMap, SizeOf(TColorMap)*k );
tmcl:=CM^.cTo;
curcl:=RGB(Bits[CO], Bits[CO+1], Bits[CO+2]);
if curcl = CM^.cFrom then begin
CopyMemory(@tm[3], @tmcl, 1 );
CopyMemory(@tm[2], IncPt( @tmcl, 1 ), 1);
CopyMemory(@tm[1], IncPt(@tmcl, 2), 1);
CopyMemory(@tmcl, @tm[1], 3 );
CopyMemory(@Bits[CO], @tmcl, 3);
end;
end;
end;
end;
SetDIBits(DC, Result, 1, bm.bmHeight, @Bits[0], bi, DIB_RGB_COLORS);
DeleteDC(DC);
end;
И ещё пара вопросиков:
1)при прохождении по этим битовым полям у меня последняя строчка в битмапе всё-равно остаётся в прежних цветах. Что в приведённом мной примере не так?
2) если посмотреть содержимое миссива куда я записываю данные, то в конце остаётся "хвост" из нулевых байтов. Как мне правильно определить размерность массива?
← →
SPeller (2002-09-06 02:51) [5]PS: текст фунции IncPt, мож кому пригодится:
function IncPt( P: Pointer; Plus: Integer ): Pointer;
begin
Result := Pointer( Integer( P ) + Plus );
end;
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2002.10.21;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.008 c