我贴一段代码:
Function YUV422ToBmp(Width,Height:Integer; inBuf
ointer):TBitmap;
Const
PixelCountMax = 32768;
Type
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = ARRAY[0..PixelCountMax-1] OF TRGBTriple;
TArrayInteger=Array of Integer;
TArrayByte=Array of Byte;
Var
YBufferSize, UVBufferSize:Integer;
YBuffer,UBuffer,VBuffer:TArrayByte;
ULine,VLine:TArrayInteger;
R, G, B:Integer;
Y, U, V:Integer;
Line:Integer;
First,Last:Integer;
UVIndex, pixel:Integer;
YIndex,RGBIndex:Integer;
Row: pRGBTripleArray;
Function CheckValue(Value:SmallInt):Byte;
begin
if Value<0 then
begin
Result:=0;
end
else
begin
if Value>255 then
Result:=255
else
Result:=R;
end;
// Result:=255-Result;
end;
begin
Result:= TBitmap.Create;
Result.PixelFormat := pf24bit;
Result.Width := Width;
Result.Height := Height;
//Allocate memory for input and output buffers.
YBufferSize := height*width;
SetLength(YBuffer,YBufferSize);
UVBufferSize := (height*width) div 2;
SetLength(UBuffer,UVBufferSize);
SetLength(VBuffer,UVBufferSize);
SetLength(ULine,width+2);
SetLength(VLine,width+2);
ZeroMemory(ULine, SizeOf(Integer)*(width+2));
ZeroMemory(VLine, SizeOf(Integer)*(width+2));
Try
//Read frames of Y then U then V components
MoveMemory(YBuffer,inBuf,YBufferSize);
inBuf:=PChar(inBuf)+YBufferSize;
MoveMemory(UBuffer,inBuf,UVBufferSize);
inBuf:=PChar(inBuf)+UVBufferSize;
MoveMemory(VBuffer,inBuf,UVBufferSize);
inBuf:=PChar(inBuf)+UVBufferSize;
for Line:=0 to Height-1 do
begin
UVIndex := (width*line) div 2;
pixel:=0;
While pixel<width do
begin
//Copy (sub-sampled) UV components to line buffer.
ULine[pixel] := UBuffer[UVIndex]-128;
VLine[pixel] := VBuffer[UVIndex]-128;
Inc(UVIndex);
Inc(pixel,2);
end;
YIndex := width*line;
RGBIndex := 3*width*line;
Row := Result.Scanline[Line];
for pixel:=0 to width-1 do
begin
//Copy Y value and filter UV values.
{
Y:=YBuffer[YIndex];
U:=ULine[pixel];
V:=VLine[pixel];
R:=Round(Y+1.371*(V-128));
G:=Round(Y-0.698*(V-128)-0.336*(U-128));
B:=Round(Y+1.732*(U-128));
}
Y := YBuffer[YIndex] - 16;
Inc(YIndex);
if pixel=0 then
begin
First := 0;
end
else
begin
First := ULine[pixel-1];
end;
if pixel=Width-1 then
Last:=0
else
Last:=VLine[pixel+1];
U := (First+2*ULine[pixel]+Last+1) shr 1;
V := (First+2*VLine[pixel]+Last+1) shr 1;
// Matrix YUV to RGB
R := (298*Y+409*V+128) shr 8;
G := (298*Y-100*U-208*V + 128) shr 8;
B := (298*Y+516*U+128) shr 8;
With Row[pixel] do
begin
rgbtRed := CheckValue(R);
rgbtGreen := CheckValue(G);
rgbtBlue := CheckValue(B);
end;
end;
end;
Finally
SetLength(VLine,0);
SetLength(ULine,0);
SetLength(VBuffer,0);
SetLength(UBuffer,0);
SetLength(YBuffer,0);
end;
end;