Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 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.054 c
9-1075751438
mx
2004-02-02 22:50
2004.05.30
скролл фона.


4-1081364941
Дубинин Алексей
2004-04-07 23:09
2004.05.30
Как уменьшить количество ОЗУ занимаемой программой


3-1084116682
Alleum
2004-05-09 19:31
2004.05.30
реализовать перемену строк местами


9-1075218805
Night Flame
2004-01-27 18:53
2004.05.30
Игра "Пять крестов"


3-1084279983
Klerk
2004-05-11 16:53
2004.05.30
Вставить данные





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский