Форум: "Игры";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];
ВнизПеревод цвета из 24 бит в 16 бит Найти похожие ветки
← →
Lucky[ELF] © (2004-02-03 00:10) [0]Есть 24 бита цвета (RGB) как их перевести 16 бит? Компоненты не и другие средства не предлагать, только общедоступные математические действия.
Спасибо! С уважением.
← →
Mihey © (2004-02-03 00:45) [1]Точно 24 bit -> 16 bit? Вот тута есть:
http://www.efg2.com/Lab/ImageProcessing/Scanline.htm
← →
MBo © (2004-02-03 07:16) [2]принцип здесь посмотри
http://www.delphimaster.ru/articles/pixels/index.html
← →
cyborg © (2004-02-03 11:59) [3]
R:=RByte shr 3; //деление на 8
G:=GByte shr 2; //деление на 4
B:=BByte shr 3;
WordColor565:=Word((R) or (G SHL 5) or (B SHL 11));
← →
Lucky[ELF] © (2004-02-03 19:07) [4]
> cyborg © (03.02.04 11:59) [3]
>
> R:=RByte shr 3; //деление на 8
> G:=GByte shr 2; //деление на 4
> B:=BByte shr 3;
> WordColor565:=Word((R) or (G SHL 5) or (B SHL 11));
Огромный тебе респект, а то я задолбался лазить по найденным мною страницам! там почти визде пишут так RByte / коэф, GByte / коэф, BByte / коэф, и дальше еще операции, но блин нигде по тексту эти коэффициенты не определены :(
осталось тока понять, что означает shr и SHL, хотите смейтесь, хотите нет, но я пишу на сях, а там вроде такого нет, а на пасе я знаю только минимум, но думаю это уже не проблема - D7 есть в нем спавка etc
спасибо всем за потраченное время и за ресурсы тоже, плохо тока что они на басурманском, я его почти не знаю :(
С уважением Lucky[ELF]
← →
cyborg © (2004-02-03 20:51) [5]shl и shr это битовый сдвиг влево и сдвиг вправо.
shr 3 равносильно div 8
shl 5 равносильно умножению на 32.
Вместо "долгого" деления или умножения лучше всего делать побитовый сдвиг если делитель кратен двойке.
В данном случае просто двигаем бити на свои места
G shl 5
Byte(00111111) - Word(0000011111100000)
сдвиг влево на 5 битов
← →
VMcL © (2004-02-03 20:55) [6]>>Lucky[ELF] © (03.02.04 19:07) [4]
>>осталось тока понять, что означает shr и SHL, хотите смейтесь, хотите нет, но я пишу на сях, а там вроде такого нет
<< -- shl
>> -- shr
← →
Lucky[ELF] © (2004-02-03 22:59) [7]
> VMcL © (03.02.04 20:55) [6]
Спасибо все стало на свои места!
← →
Lucky[ELF] © (2004-02-04 00:00) [8]
> cyborg © (03.02.04 11:59) [3]
>
> R:=RByte shr 3; //деление на 8
> G:=GByte shr 2; //деление на 4
> B:=BByte shr 3;
> WordColor565:=Word((R) or (G SHL 5) or (B SHL 11));
блин! косяк, картинка рисуется, но теперь проблема с цветами, у меня теперь цвет который раньше назвался CYAN у меня стал YELLOW, в чем проблема? bmp-ка сделана в pbrush aka Паинт.
Спасибо!
← →
VMcL © (2004-02-04 19:14) [9]>>Lucky[ELF] © (04.02.04 00:00) [8]
Код в студию.
← →
KA_ © (2004-02-04 19:18) [10]Какого типа R, G и B?
← →
Lucky[ELF] © (2004-02-04 19:31) [11]Код без проблем! но он на сях :(
Я тока не знаю этого хватит? если нет, то пишите, что конкретно, а то проект большой.
В этой функции все происходит, там много закоментированно.
//===========================================================================
// Render functions
#define LOGS(s) {FILE *f=fopen("logs.txt","at"); fprintf(f,"%s",s); fclose(f);};
spriteTag* Render_LoadSprite (packfile_t *pf, char *filename)
{
/* spriteTag *newSprite = new spriteTag;
newSprite->xsize = 800;
newSprite->ysize = 600;
if (!newSprite)
return NULL;
if (DirectDraw7_CreateSurface ( &(newSprite->Surf), newSprite->xsize, newSprite->ysize ) != 0 )
return NULL;
DirectDraw7_SetColorKey (newSprite->Surf, SPRITE_RED, SPRITE_GREEN, SPRITE_BLUE);
DirectDraw7_ClearSurface (newSprite->Surf, 0, 0, 255, NULL);
return newSprite;*/
///////////////////////////////////////////////////////////////////////////////
char *buf_data; // Буфер данных
int filesize = PackFileGet (pf, filename, &buf_data); // Грузи данные в буффер
if (filesize == 0) // Если ничего не загрузилось
{
free (buf_data);
return NULL;
}
if (*buf_data == NULL) // Если ничего не загрузилось
{
return NULL;
}
// Копируем заголовок
BITMAPFILEHEADER bmpHEAD;
memcpy (&bmpHEAD, buf_data, sizeof(bmpHEAD));
// Проверяем, действительно ли это БМП файл
char *bmpType = (char*)&bmpHEAD.bfType;
if (*bmpType != "B" || *++bmpType != "M") // Если нет
{
free (buf_data);
return NULL;
}
// Копируем второй - информацинный заголовок
BITMAPINFOHEADER bmpINFO;
memcpy (&bmpINFO, buf_data + sizeof(bmpHEAD), sizeof(bmpINFO));
if (bmpINFO.biCompression != BI_RGB) // Не сжатое ли изображение
{
free (buf_data);
return NULL;
}
if (bmpINFO.biBitCount != 24 || resolutionBPP != 16) // Устраивает ли нас пиксели
{
free (buf_data);
return NULL;
}
//////////////////////////////////////////////////////////////////////////////////
// Выделяем место
spriteTag *newSprite = new spriteTag;
// Если не удалось выделеть место, то гуляй Вася
if (!newSprite)
{
free (buf_data);
return NULL;
}
newSprite->xsize = bmpINFO.biWidth;
newSprite->ysize = bmpINFO.biHeight;
//////////////////////////////////////////////////////////////////////////////////
// Создаем поверхность
if (DirectDraw7_CreateSurface ( &(newSprite->Surf), newSprite->xsize, newSprite->ysize ) != 0 )
{
free (buf_data);
delete newSprite;
return NULL;
}
DirectDraw7_SetColorKey (newSprite->Surf, SPRITE_RED, SPRITE_GREEN, SPRITE_BLUE);
DirectDraw7_ClearSurface (newSprite->Surf, 0, 255, 0, NULL);
// Вычисляем размер изображения, если нужно
int ImageSize = bmpINFO.biSizeImage;
if (ImageSize == 0)
ImageSize = ((bmpINFO.biWidth*(bmpINFO.biBitCount/8)+3 & ~3)*bmpINFO.biHeight);
// BITMAP ------------------------------------------------------------
/* BYTE *bmpbuf = (BYTE*)(buf_data + sizeof(bmpHEAD) + bmpINFO.biSize);
HBITMAP hbm = CreateBitmap (bmpINFO.biWidth, bmpINFO.biHeight, bmpINFO.biPlanes, bmpINFO.biBitCount, bmpbuf);
if ( DirectDraw7_Copy_BMP( &(newSprite -> Surf), hbm ) != 0 )
{
free (buf_data);
delete newSprite;
return false;
}
// DeleteObject( hbm );
LOGS ("BMP is copy\n");
free (buf_data);
return newSprite;
*/
/*
BITMAP bm;
ZeroMemory (&bm, sizeof(bm));
bm.bmHeight = bmpINFO.biHeight;
bm.bmWidth = bmpINFO.biWidth;
bm.bmBitsPixel = bmpINFO.biBitCount;
bm.bmWidthBytes = bmpINFO.biWidth * 3;
//bm.bmBits =
BYTE *bBytes = new BYTE [bmpINFO.biSizeImage];
if (!bm.bmBits)
{
free (buf_data);
delete sprite;
return false;
}*/
//BYTE *bmpbuf = (BYTE*)(buf_data + sizeof(bmpHEAD) + bmpINFO.biSize);
//memcpy (&bm.bmBits, bmpbuf, bmpINFO.biSizeImage);
///////////////////////////////////////////////////////////////////////////////////
// Copy BMP to Surface
LOGS ("-=-=-=-=- Start copy BMP to Surface -=-=-=-=-\n");
BYTE *bmpbuf = (BYTE*)(buf_data + sizeof(bmpHEAD) + bmpINFO.biSize);
DDSURFACEDESC2 desc;
ZeroMemory (&desc, sizeof (desc));
desc.dwSize = sizeof (desc);
/*HRESULT r;
while ((r = newSprite->Surf->Lock (0, &desc, DDLOCK_WAIT, 0)) == DDERR_WASSTILLDRAWING);*/
HRESULT r = newSprite->Surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 );
if (r != DD_OK)
{
free (buf_data);
delete newSprite;
return false;
}
LOGS ("Surface lock ok\n");
int BytesRequired = bmpINFO.biWidth * 3;
int BytesGiven = (BytesRequired + 3) & ~3;
BYTE *surfBits = (BYTE*)desc.lpSurface;
BYTE *imageBits = (BYTE*)(&bmpbuf[(bmpINFO.biHeight-1)*BytesGiven]);
LOGS ("Start cicle\n");
float REDdiv = (float)256/(float)pow (2, 5);
float GREENdiv = (float)256/(float)pow (2, 5);
float BLUEdiv = (float)256/(float)pow (2, 5);
for (int i=0; i<bmpINFO.biHeight; i++)
{
WORD *pixptr = (WORD*)surfBits;
RGBTRIPLE *triple = (RGBTRIPLE*)imageBits;
//LOGS ("Start cicle 2\n");
for (int p=0; p<bmpINFO.biWidth; p++)
{
//LOGS ("Start cicle 3\n");
//WORD color = DirectDraw7_ConvertRGB ( newSprite->Surf, RGB (triple->rgbtRed, triple->rgbtGreen, triple->rgbtBlue));
//WORD color = DirectDraw7_ConvertRGB ( newSprite->Surf, RGB (0, 0, 0));
//*pixptr = (WORD)RGB (triple->rgbtRed, triple->rgbtGreen, triple->rgbtBlue);
//*pixptr = (WORD)RGB (0,0,255);
//float rf = (float)triple->rgbtRed/REDdiv;
//float gf = (float)triple->rgbtGreen/GREENdiv;
//float bf = (float)triple->rgbtBlue/BLUEdiv;
WORD rf = triple->rgbtRed >> 3;
WORD gf = triple->rgbtGreen >> 2;
WORD bf = triple->rgbtBlue >> 3;
*pixptr = (WORD)(rf | (gf << 5) | (bf << 11));
//WORD r=(WORD)((WORD)rf<<0);
//WORD g=(WORD)((WORD)gf<<5);
//WORD b=(WORD)((WORD)bf<<11);
//*pixptr = (WORD)(r|g|b);
//*pixptr = (WORD)(0x00|0xFF00|0x00);
/* WORD color = (WORD)RGB (rf, gf, bf);
*pixptr = (WORD)color;
*/
triple++;
pixptr++;
}
surfBits += desc.lPitch;
imageBits -= BytesGiven;
}
newSprite->Surf->Unlock (NULL);
LOGS ("Surface Unlock\n");
return newSprite;
}
> KA_ © (04.02.04 19:18) [10]
> Какого типа R, G и B?
А как это определить?
← →
KA_ © (2004-02-04 19:39) [12]> WORD rf = triple->rgbtRed >> 3;
> WORD gf = triple->rgbtGreen >> 2;
> WORD bf = triple->rgbtBlue >> 3;
По-моему, не WORD, а BYTE.
← →
cyborg © (2004-02-04 20:00) [13]все переменные байты, слово только получаемый 16 битовый цвет.
Возможно просто поменяй местами в коде байты R с B
← →
cyborg © (2004-02-04 20:10) [14]Вот моя функция по конвертированию, немного не доделал, хотел ещё сделать поддержку 8 битовых палитровых данных в 16 бит, но за ненадобностью этого не сделал.
//Преобразование данных
Function ConvertPicture(Var SrcPicture : Pointer; Var DestPicture : Pointer;
BPP: byte;W,H : Cardinal; Palette : Pointer) : boolean;
Var
Size : Cardinal;
I,X,Y : Integer;
R,G,B : Byte;
begin
Result:=false;
Size:=(W*H*BPP) div 8;
GetMem(DestPicture,(W*H)*2); //выделение памяти, по 2 байта на пиксел
Case BPP of
24 : begin
for I:=0 to (Size div 3)-1 do
begin
Y:=I div W;
X:=I-(Y*W);
R:=TSrcPicture(SrcPicture^)[I*3] div 8;
G:=TSrcPicture(SrcPicture^)[I*3+1] div 4;
B:=TSrcPicture(SrcPicture^)[I*3+2] div 8;
TDestPicture(DestPicture^)[((H-Y-1)*W)+X]:=
Word((R) or (G SHL 5) or (B SHL 11));
end; //for I:=1 to Size do
end;
else begin
FreeMem(DestPicture,(W*H)*2);
DestPicture:=Nil;
end;
end;//case BPP
Result:=True;
end;
где:
Var SrcPicture - исходные данные (24 битовые в данном случае), просто указать адрес начала пикселей из BMP в памяти, некоторые BMP хранятся перевёрнутые здесь это не учитывается.
Var DestPicture - возвращаемый указатель на блок 16 битовых пикселей
← →
Lucky[ELF] © (2004-02-04 20:15) [15]Да все решилось заменой R на B байтов, да слова на байты тоже заменил. теперь все в порядке.
> cyborg © (03.02.04 11:59) [3]
>
> R:=RByte shr 3; //деление на 8
> G:=GByte shr 2; //деление на 4
> B:=BByte shr 3;
> WordColor565:=Word((R) or (G SHL 5) or (B SHL 11));
типы не были указаны вот я и поставил WORD.
Спасибо за помощь!
ЗюЫю а вечером здесь быстро ответ на вопрос можно найти, всего за 50 мин нашел ответ на который искал ответ более месяца :-(
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.026 c