提供一组直接将YUV数据转换为位图的函数,就是GetOriginalImage得到的图形数据,海康的好象是YUV422P的
function YUV422P_TO_BMP(const Buffer: PChar; AWidth, AHeight: Integer;
Bitmap: TBitmap): Boolean;
var
YPlannar, UPlannar, VPlannar: PByte;
PlannarSize: Integer;
i, j, k: Integer;
Y1, Y2, U, V: Integer;
R, G, B: Integer;
P: PByte;
begin
Result := False;
if Odd(AWidth) or Odd(AHeight) or (AWidth <= 0) or (AHeight <= 0) then
Exit;
PlannarSize := AWidth * AHeight;
if not Assigned(Bitmap) then
Exit;
with Bitmap do
begin
PixelFormat := pf24bit;
Width := AWidth;
Height := AHeight;
end;
YPlannar := PByte(Buffer);
UPlannar := PByte(Buffer+PlannarSize);
VPlannar := PByte(Buffer+PlannarSize+PlannarSize div 2);
i := 0;
k := 0;
while (i < PlannarSize) do
begin
j := 0;
P := Bitmap.ScanLine[k];
while (j < AWidth) do
begin
Y1 := YPlannar^;
Inc(YPlannar);
Y2 := YPlannar^;
Inc(YPlannar);
U := UPlannar^;
Inc(UPlannar);
V := VPlannar^;
Inc(VPlannar);
B := (1164 * (Y1 - 16) + 2018 * (U - 128)) div 1000;
G := (1164 * (Y1 - 16) - 813 * (V - 128) - 391 * (U - 128)) div 1000;
R := (1164 * (Y1 - 16) + 1596 * (V - 128)) div 1000;
if B > $FF then B := $FF
else if B < 0 then B := 0;
if G > $FF then G := $FF
else if G < 0 then G := 0;
if R > $FF then R := $FF
else if R < 0 then R := 0;
P^ := B;
Inc(P);
P^ := G;
Inc(P);
P^ := R;
Inc(P);
B := (1164 * (Y2 - 16) + 2018 * (U - 128)) div 1000;
G := (1164 * (Y2 - 16) - 813 * (V - 128) - 391 * (U - 128)) div 1000;
R := (1164 * (Y2 - 16) + 1596 * (V - 128)) div 1000;
if B > $FF then B := $FF
else if B < 0 then B := 0;
if G > $FF then G := $FF
else if G < 0 then G := 0;
if R > $FF then R := $FF
else if R < 0 then R := 0;
P^ := B;
Inc(P);
P^ := G;
Inc(P);
P^ := R;
Inc(P);
Inc(j, 2);
Inc(i, 2);
end;
Inc(k);
end;
Result := True;
end;
function BMP_TO_YUV422P(Bitmap: TBitmap; Buffer: PChar;
var BufSize: Cardinal): Boolean;
var
YPlannar, UPlannar, VPlannar: PByte;
PlannarSize: Cardinal;
W,H: Integer;
i, j: Integer;
R,G,B: Integer;
y1,u1,v1,y2,u2,v2: Integer;
P: PByte;
begin
Result := False;
if not Assigned(Bitmap) then
Exit;
with Bitmap do
begin
if PixelFormat <> pf24bit then
PixelFormat := pf24bit;
if Odd(Width) or Odd(Height) or (Width = 0) or (Height = 0) then
Exit;
W := Width;
H := Height;
PlannarSize := W * H * 2;
end;
if BufSize < PlannarSize then
begin
BufSize := PlannarSize;
Exit;
end;
BufSize := PlannarSize;
YPlannar := PByte(Buffer);
UPlannar := PByte(Buffer + W * H);
VPlannar := PByte(Buffer + W * H + W * H div 2);
for i := 0 to H - 1 do
begin
P := PByte(Bitmap.ScanLine
);
for j := 0 to W div 2 - 1 do
begin
B := P^;
Inc(P);
G := P^;
Inc(P);
R := P^;
Inc(P);
y1 := (257 * R + 504 * G + 98 * B) div 1000 + 16;
u1 := (-148 * R - 291 * G + 439 * B) div 1000 + 128;
v1 := (439 * R - 368 * G - 71 * B) div 1000 + 128;
B := P^;
Inc(P);
G := P^;
Inc(P);
R := P^;
Inc(P);
y2 := (257 * R + 504 * G + 98 * B) div 1000 + 16;
u2 := (-148 * R - 291 * G + 439 * B) div 1000 + 128;
v2 := (439 * R - 368 * G - 71 * B) div 1000 + 128;
YPlannar^ := y1;
Inc(YPlannar);
YPlannar^ := y2;
Inc(YPlannar);
UPlannar^ := (u1 + u2) div 2;
Inc(UPlannar);
VPlannar^ := (v1 + v2) div 2;
Inc(VPlannar);
end;
end;
Result := True;
end;
function YUV422_TO_BMP(const Buffer: PChar; AWidth, AHeight: Integer;
Bitmap: TBitmap): Boolean;
var
yuv: PByte;
Size: Integer;
i, j, k: Integer;
Y1, Y2, U, V: Integer;
R, G, B: Integer;
P: PByte;
begin
Result := False;
if Odd(AWidth) or Odd(AHeight) or (AWidth <= 0) or (AHeight <= 0) then
Exit;
Size := AWidth * AHeight;
if not Assigned(Bitmap) then
Exit;
with Bitmap do
begin
PixelFormat := pf24bit;
Width := AWidth;
Height := AHeight;
end;
yuv := PByte(Buffer);
i := 0;
k := 0;
while (i < Size) do
begin
j := 0;
P := Bitmap.ScanLine[k];
while (j < AWidth) do
begin
U := yuv^;
Inc(yuv);
Y1 := yuv^;
Inc(yuv);
V := yuv^;
Inc(yuv);
Y2 := yuv^;
Inc(yuv);
B := (1164 * (Y1 - 16) + 2018 * (U - 128)) div 1000;
G := (1164 * (Y1 - 16) - 813 * (V - 128) - 391 * (U - 128)) div 1000;
R := (1164 * (Y1 - 16) + 1596 * (V - 128)) div 1000;
if B > $FF then B := $FF
else if B < 0 then B := 0;
if G > $FF then G := $FF
else if G < 0 then G := 0;
if R > $FF then R := $FF
else if R < 0 then R := 0;
P^ := B;
Inc(P);
P^ := G;
Inc(P);
P^ := R;
Inc(P);
B := (1164 * (Y2 - 16) + 2018 * (U - 128)) div 1000;
G := (1164 * (Y2 - 16) - 813 * (V - 128) - 391 * (U - 128)) div 1000;
R := (1164 * (Y2 - 16) + 1596 * (V - 128)) div 1000;
if B > $FF then B := $FF
else if B < 0 then B := 0;
if G > $FF then G := $FF
else if G < 0 then G := 0;
if R > $FF then R := $FF
else if R < 0 then R := 0;
P^ := B;
Inc(P);
P^ := G;
Inc(P);
P^ := R;
Inc(P);
Inc(j, 2);
Inc(i, 2);
end;
Inc(k);
end;
Result := True;
end;
function BMP_TO_YUV422(Bitmap: TBitmap; Buffer: PChar;
var BufSize: Cardinal): Boolean;
var
yuv: PByte;
Size: Cardinal;
W,H: Integer;
i, j: Integer;
R,G,B: Integer;
y1,u1,v1,y2,u2,v2: Integer;
P: PByte;
begin
Result := False;
if not Assigned(Bitmap) then
Exit;
with Bitmap do
begin
if Odd(Width) or Odd(Height) or (Width = 0) or (Height = 0) then
Exit;
W := Width;
H := Height;
Size := W * H * 2;
if BufSize < Size then
begin
BufSize := Size;
Exit;
end;
BufSize := Size;
yuv := PByte(Buffer);
if PixelFormat <> pf24bit then
PixelFormat := pf24bit;
end;
for i := 0 to H - 1 do
begin
P := PByte(Bitmap.ScanLine);
for j := 0 to W div 2 - 1 do
begin
B := P^;
Inc(P);
G := P^;
Inc(P);
R := P^;
Inc(P);
y1 := (257 * R + 504 * G + 98 * B) div 1000 + 16;
u1 := (-148 * R - 291 * G + 439 * B) div 1000 + 128;
v1 := (439 * R - 368 * G - 71 * B) div 1000 + 128;
//y1 := (299 * R + 587 * G + 114 * B) div 1000;
//u1 := ((B - y1) * 565) div 1000;
//v1 := ((R - y1) * 713) div 1000;
B := P^;
Inc(P);
G := P^;
Inc(P);
R := P^;
Inc(P);
y2 := (257 * R + 504 * G + 98 * B) div 1000 + 16;
u2 := (-148 * R - 291 * G + 439 * B) div 1000 + 128;
v2 := (439 * R - 368 * G - 71 * B) div 1000 + 128;
//y2 := (299 * R + 587 * G + 114 * B) div 1000;
//u2 := ((B - y2) * 565) div 1000;
//v2 := ((R - y2) * 713) div 1000;
yuv^ := (u1 + u2) div 2;
Inc(yuv);
yuv^ := y1;
Inc(yuv);
yuv^ := (v1 + v2) div 2;
Inc(yuv);
yuv^ := y2;
Inc(yuv);
end;
end;
Result := True;
end;
function YV12_TO_BMP(const Buffer: PChar; AWidth, AHeight: Integer;
Bitmap: TBitmap): Boolean;
var
y, u, v: PByte;
Size: Integer;
i, j, k: Integer;
Y1, Y2, U1, V1: Integer;
R, G, B: Integer;
P: PByte;
begin
Result := False;
if Odd(AWidth) or Odd(AHeight) or (AWidth <= 0) or (AHeight <= 0) then
Exit;
Size := AWidth * AHeight;
if not Assigned(Bitmap) then
Exit;
with Bitmap do
begin
PixelFormat := pf24bit;
Width := AWidth;
Height := AHeight;
end;
y := PByte(Buffer);
u := PByte(Integer + Size);
v := PByte(Integer(u) + Size div 4);
i := 0;
k := 0;
while (i < Size) do
begin
j := 0;
P := Bitmap.ScanLine[k];
while (j < AWidth) do
begin
Y1 := y^;
Inc;
Y2 := y^;
Inc;
U1 := u^;
Inc(u);
V1 := v^;
Inc(v);
B := (1164 * (Y1 - 16) + 2018 * (U1 - 128)) div 1000;
G := (1164 * (Y1 - 16) - 813 * (V1 - 128) - 391 * (U1 - 128)) div 1000;
R := (1164 * (Y1 - 16) + 1596 * (V1 - 128)) div 1000;
if B > $FF then B := $FF
else if B < 0 then B := 0;
if G > $FF then G := $FF
else if G < 0 then G := 0;
if R > $FF then R := $FF
else if R < 0 then R := 0;
P^ := B;
Inc(P);
P^ := G;
Inc(P);
P^ := R;
Inc(P);
B := (1164 * (Y2 - 16) + 2018 * (U1 - 128)) div 1000;
G := (1164 * (Y2 - 16) - 813 * (V1 - 128) - 391 * (U1 - 128)) div 1000;
R := (1164 * (Y2 - 16) + 1596 * (V1 - 128)) div 1000;
if B > $FF then B := $FF
else if B < 0 then B := 0;
if G > $FF then G := $FF
else if G < 0 then G := 0;
if R > $FF then R := $FF
else if R < 0 then R := 0;
P^ := B;
Inc(P);
P^ := G;
Inc(P);
P^ := R;
Inc(P);
Inc(j, 2);
Inc(i, 2);
end;
Inc(k);
if k mod 2 <> 0 then
begin
Dec(u, AWidth div 2);
Dec(v, AWidth div 2);
end;
end;
Result := True;
end;