Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.30;
Скачать: CL | DM;

Вниз

Перевод цвета из 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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.022 c
7-1082445218
Ozone
2004-04-20 11:13
2004.05.30
Com - порт


1-1084741869
Mishenka
2004-05-17 01:11
2004.05.30
Удаление списка?


11-1074101780
Phantomaz
2004-01-14 20:36
2004.05.30
Как поместить рисунок из ресурса (иконку) в PopupMenu ?


4-1082096789
Mamed
2004-04-16 10:26
2004.05.30
printer page Orientation


3-1083660291
han-bratan
2004-05-04 12:44
2004.05.30
тип данных Мемо