Работал с камерой, от которой получал картинку — буффер и его длину. Проблема в том, что картинка с камеры
идет в формате i420..экономит канал

...нодо конвертнуть i420 в RGB. Изучив информацию, которая приводится на
www.fourcc.org
набросал код, который вроде бы должен работать...и он работает, но картинка частично "плывет". Возможно кто-нибудь уже сталкивался с такой проблемой..и если да — имеет кусок кода осуществляющего данное преобразование. В любом случае, привожу код, посмотрите — может у Вас получится увидеть ошибку, которую не вижу я.
Заранее благодарен.
struct TM_YUV
{
TM_YUV(){ Y=0; U=0; V=0; };
BYTE Y;
BYTE U;
BYTE V;
};
//---------------------------------------------------------------------------
struct TM_RGB24
{
TM_RGB24(){ R=0; G=0; B=0; };
BYTE R;
BYTE G;
BYTE B;
};
//---------------------------------------------------------------------------
пример набросан в среде борланд с++ билдер 6.0
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
Graphics::TBitmap* bmp = new Graphics::TBitmap();
bmp->Width = 352;
bmp->Height = 288;
bmp->PixelFormat = pf24bit;
vector<BYTE> i420; // данные формата i420
vector<TM_YUV> yuv; // данные формата YUV
vector<TM_RGB24> rgb; // данные RGB
// в файле "i420image.dat" содержатся данные одной картники формата i420
TFileStream* fs = new TFileStream( ExtractFilePath(Application->ExeName) + "i420image.dat", fmOpenRead );
i420.resize( fs->Size );
fs->Read( i420.begin(), fs->Size );
delete fs;
yuv.resize(bmp->Width*bmp->Height);
// Переписали все компоненты яркости, в данном формате их по каждой на пиксел
for( int i = 0; i < bmp->Width*bmp->Height; i++ )
{
yuv[i].Y = i420[i];
}
int Counter = 0;
// Теперь компоненты цветоразностей, они одинаковы в каждом макропикселе, который представляет собой квадрат размером 2х2 пиксела
for( int i = 0; i < bmp->Width*bmp->Height/4; i++ )
{
yuv[Counter].U =
yuv[Counter + 1].U =
yuv[Counter + bmp->Width].U =
yuv[Counter + bmp->Width + 1].U = i420[bmp->Width*bmp->Height + i];
yuv[Counter].V =
yuv[Counter + 1].V =
yuv[Counter + bmp->Width].V =
yuv[Counter + bmp->Width + 1].V = i420[bmp->Width*bmp->Height + i + bmp->Width*bmp->Height/4];
Counter += 2;
if( Counter%bmp->Width == 0 )
if( (Counter/bmp->Width)%2 != 0 )
Counter += bmp->Width;
}
// теперь конфертнем из YUV в RGB
rgb.resize( bmp->Width*bmp->Height );
for( int i = 0; i < rgb.size(); i++ )
{
rgb[i].B = 1.164*(yuv[i].Y - 16) + 2.018*(yuv[i].U - 128);
rgb[i].G = 1.164*(yuv[i].Y - 16) - 0.813*(yuv[i].V - 128) - 0.391*(yuv[i].U - 128);
rgb[i].R = 1.164*(yuv[i].Y - 16) + 1.596*(yuv[i].V - 128);
}
// выведем на канву формы
for( int y = 0; y < bmp->Height; y++ )
{
Byte* ptr = (Byte*)bmp->ScanLine[y];
int c=0;
for(int x = 0; x < bmp->Width; x++)
{
ptr[c] = rgb[y*bmp->Width + x].B;
ptr[c+1] = rgb[y*bmp->Width + x].G;
ptr[c+2] = rgb[y*bmp->Width + x].R;
c+=3;
}
}
Canvas->Draw( 0, 0, bmp );
delete bmp;
}