?
Hier hast Du es mit Dependent und Independent Maps zu tun, wenn dein Video
ein 2 Farben -Bild zeichnet macht es das mit der über HAL verkapselten
Fähigkeit deiner Grafikkarte.
Diese Fähigkeiten werden durch Dibsektionen verkapselt.
Wenn du nur mit CreateBitmap und GetBitmap handelst wirst du immer
andere Pixelformate erlangen als Du möchtest.
Das beste ist Du erstellst eine Dibsektion deiner Wunschformatierung:
Pseudeo:
::DrawDibOpen();
m_hBmp = ::CreateDIBSection(m_hDC, m_pBitmapInfo, DIB_RGB_COLORS, (void**)&m_pDat, NULL, NULL);
if(!(m_hDC = ::CreateCompatibleDC(0))) //Dc erzeugen
;
//dc mit compatible bitmap verbinden
m_hOldBitmap = (HBITMAP)::SelectObject (m_hDC, m_hBmp);
Ein Wunschvorlage für dein Zielformat legst Du in einer Bitmapinfo an:
Pseudo:
bool CDib::AllocBitmapInfo(BITMAPINFO **ppBitmapInfo, int Width, int Height, int Bpp)
{
*ppBitmapInfo = (BITMAPINFO*)(new char[sizeof(BITMAPINFOHEADER) + ((Bpp == 8 ? 256 : 1)*sizeof(RGBQUAD))]);
if (!*ppBitmapInfo)
return FALSE;
(*ppBitmapInfo)->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
(*ppBitmapInfo)->bmiHeader.biWidth = Width;
(*ppBitmapInfo)->bmiHeader.biHeight = Height;//Bpp==8|Bpp==24?-Height:Height;//botomup
(*ppBitmapInfo)->bmiHeader.biPlanes = 1;
(*ppBitmapInfo)->bmiHeader.biBitCount = Bpp;
(*ppBitmapInfo)->bmiHeader.biCompression = BI_RGB;
(*ppBitmapInfo)->bmiHeader.biSizeImage = Width*abs(Height)*(Bpp >> 3);
(*ppBitmapInfo)->bmiHeader.biXPelsPerMeter = 0;
(*ppBitmapInfo)->bmiHeader.biYPelsPerMeter = 0;
(*ppBitmapInfo)->bmiHeader.biClrUsed = Bpp == 8 ? 256 : 0;
(*ppBitmapInfo)->bmiHeader.biClrImportant = 0;
if ((*ppBitmapInfo)->bmiHeader.biClrUsed)
SetColorbasis(*ppBitmapInfo, RGB(255, 255, 255), 1);
return true;
}
//ist dein Wuschziel ein 256 Farben Bild musst Du die indizierten Farben
//anhängen hier Grau natürlich.
void CDib::SetColorbasis(BITMAPINFO *pBmi, COLORREF basecol, BYTE chanels, bool setgraymap/*= true*/)
{
if(!pBmi)
{
if(!m_pBitmapInfo)
return;
pBmi = m_pBitmapInfo;
}
int step = max((chanels/8)*8,1);
int loops = pBmi->bmiHeader.biClrUsed-(step>1?step:0);
for(int i = 0; i < loops; i+=step)
for(int n = 0; n < step; n++)
{
float r((GetRValue(basecol)/255.0f)*i),
g((GetGValue(basecol)/255.0f)*i),
b((GetBValue(basecol)/255.0f)*i);
pBmi->bmiColors[i+n].rgbRed = r;
pBmi->bmiColors[i+n].rgbGreen = g;
pBmi->bmiColors[i+n].rgbBlue = b;
pBmi->bmiColors[i+n].rgbReserved = 0;
if(setgraymap) m_GrayMap[i+n] = (r+g+b)/3;
}
}
Pseudo:
//Dann blittest Du dein Fenster in die Dibsection dabei wird sie per HArdware in unter [1ms] auf dein Zielformat gewandelt:
//hier compatible HDC aus Dibsection verwenden
::SetStretchBltMode( m_hDC ,STRETCH_DELETESCANS);
::StretchBlt( m_hDC , 0,0, rc.Width(), rc.Height(),clientDC, bw, th+bw,rcClient.Width()-bw,rcClient.Height(),SRCCOPY);
Danach hast Du unmittelbar den Zugriff auf den Bildspeicher den Du bei
CreateDIBSection angegeben hast.
Das Prinzip nutzt also die Hardware und frisst null Brot.
Wenn Du mehr Code brauchst forsche nach DibSectionen.
Grüße
Karsten