//视频回调函数
function FrameCallBack(hWnd: HWND; lpVHdr: PVIDEOHDR): DWORD; stdcall;
var
vRGB: Pointer;
begin
GetMem(vRGB, lpVHdr^.dwBufferLength);//分配内存
try
//如何吧lpVHdr^.lpData(YUV2格式的)转换到vRGB(转成RGB格式,因为编码器不支持YUV2格式)呢?
//接下来编码
finally
FreeMem(vRGB) ;
end;
Result := 1;
//发送....
end;
function FrameCallBack(hWnd: HWND; lpVHdr: PVIDEOHDR): DWORD; stdcall;
var
vRGB: Pointer;
begin
GetMem(vRGB, lpVHdr^.dwBufferLength);//分配内存
try
//如何吧lpVHdr^.lpData(YUV2格式的)转换到vRGB(转成RGB格式,因为编码器不支持YUV2格式)呢?
//接下来编码
finally
FreeMem(vRGB) ;
end;
Result := 1;
//发送....
end;
Function YUVToRGB(pPC_YUVFormat:Pchar;pPC_RGBFormat:Pchar;nWidth,nHeight:Integer):Integer;
Type
PMyByte = ^Byte;
Var
I,J:Integer;
pRGB,pRaw:PMyByte;
pY,pU,pV :PMyByte;
R,G,B :Integer;
Blue,Green,Red :Byte;
Begin
pRaw := PMyByte(pPC_YUVFormat);
pRGB := PMyByte(PPC_RGBFormat);
For I := 0 To nHeight-1 Do
Begin
pY := pRaw; {Y}
Inc(pRaw); {U}
pU := pRaw;
Inc(pRaw,2); {V}
pV := pRaw;
Inc(pRaw,nWidth*2-3); {逐行指针操作}
For J := 0 To nWidth - 1 Do
Begin
R := Round((1.0*pY^)+ (0.0*(pU^-128))+(1.375*(pV^-128)));
G := Round((1.0*pY^)+ (-0.34375*(pU^-128))+(-0.703125*(pV^-128)));
B := Round((1.0*pY^)+ (1.734375*(pU^-128))+(0.0*(pV^-128)));
IF (B>255) Then B:=255;
IF (B<0) Then B:=0;
IF (G>255) Then G:=255;
IF (G<0) Then G:=0;
IF (R>255) Then R:=255;
IF (R<0) Then R:=0;
Blue:=Byte(B);
Green:=Byte(G);
Red:=Byte(R);
pRGB^ := Blue;
Inc(pRGB);
pRGB^ := Green;
Inc(pRGB);
pRGB^ := Red;
Inc(pRGB);
Inc(pY,2);
IF (J mod 2) > 0 Then
Begin
Inc(pU,4);
Inc(pV,4);
End;
End;
End;
Result:=1;
End;
您好,我测试过该代码,但是不知道为什么转换后会图像失色很多,而且一般图像没了。
还有一个问题,请问 lpVHdr^.dwBufferLength是指lpVHdr^.lpData的大小吗?
我怎么觉得这大小有问题?
http://blog.csdn.net/suiyunonghen/archive/2009/02/04/3861910.aspx
看看
uses Windows,Classes,Graphics,Math;
function RGBToColor(R,G,B: Byte): TColor;overload;
function RGBToColor(Color : Longint): TColor;overload;
procedure ColorToYUV(RGB: TColor; out Y, Cb, Cr: byte);
function YUVtoColor(Y, Cb, Cr: Byte): TColor;
implementation
function RGBToColor(R,G,B: Byte): TColor;
begin
Result := R or (G shl 8) or (B shl 16);
end;function RGBToColor(Color : Longint): TColor;
var
R,G,B,A : Byte;
begin
R := Color and $FF;
G := (Color shr 8) and $FF;
B := (Color shr 16) and $FF;
A := $00;
Result := R or (G shl 8) or (B shl 16) or (A shl 24);
end;procedure ColorToRGB(Color: TColor; out R, G, B: Byte);
begin
R := Color and $FF;
G := (Color shr 8) and $FF;
B := (Color shr 16) and $FF;
end;
procedure ColorToCMY(Color: TColor; out C, M, Y: Byte);
var
R,G,B : Byte;
begin
ColorToRGB(Color, R, G, B);
C := 255 - R;
M := 255 - G;
Y := 255 - B;
end;
function CMYToColor(C, M, Y: Byte): TColor;
begin
Result := (255 - C) or ((255 - M) shl 8) or ((255 - Y) shl 16);
end;
function HSLtoColor(H, S, L: Double): TColor;
var
M1, M2: double;
function HueToColourValue (Hue: double) : byte;
var
V : double;
begin
if Hue < 0 then
Hue := Hue + 1
else
if Hue > 1 then
Hue := Hue - 1; if 6 * Hue < 1 then
V := M1 + (M2 - M1) * Hue * 6
else
if 2 * Hue < 1 then
V := M2
else
if 3 * Hue < 2 then
V := M1 + (M2 - M1) * (2/3 - Hue) * 6
else
V := M1;
Result := round (255 * V)
end;
var
R, G, B: byte;
begin
if S = 0 then
begin
R := round (255 * L);
G := R;
B := R
end
else
begin
if L <= 0.5 then
M2 := L * (1 + S)
else
M2 := L + S - L * S;
M1 := 2 * L - M2;
R := HueToColourValue (H + 1/3);
G := HueToColourValue (H);
B := HueToColourValue (H - 1/3)
end;
Result := RGB (R, G, B)
end;
procedure ColortoHSL(RGB: TColor; out H, S, L: double);
var
R, G, B : double;
D, Cmax, Cmin: double;
begin
R := GetRValue (RGB) / 255;
G := GetGValue (RGB) / 255;
B := GetBValue (RGB) / 255;
Cmax := Max (R, Max (G, B));
Cmin := Min (R, Min (G, B));
// calculate luminosity
L := (Cmax + Cmin) / 2;
if Cmax = Cmin then
begin
H := 0;// it's actually undefined
S := 0;
end
else
begin
D := Cmax - Cmin;
// calculate Saturation
if L < 0.5 then
S := D / (Cmax + Cmin)
else
S := D / (2 - Cmax - Cmin); // calculate Hue
D_R := (((Cmax - R) / 6) + (D / 2)) / D;
D_G := (((Cmax - G) / 6) + (D / 2)) / D;
D_B := (((Cmax - B) / 6) + (D / 2)) / D; if R = Cmax then H := (D_B - D_G)
else if G = Cmax then H := (1 / 3) + D_R - D_B
else if B = Cmax then H := (2 / 3) + D_G - D_R; if H < 0 then H := H + 1;
if H > 1 then H := H - 1;
end;
end;
procedure ColorToYUV(RGB: TColor; out Y, Cb, Cr: byte);
{
Lum (Y) ranges from 16 to 235.
Cb (U) ranges from 16 to 240.
Cr (V) ranges from 16 to 240.
}
var
R,G,B : byte;
t: Double;
begin
R := GetRValue(RGB);
G := GetGValue(RGB);
B := GetBValue(RGB); Y := Round( (0.257 * R) + (0.504 * G) + (0.098 * B) + 16 );
Cb := Round( (-0.148 * R) - (0.291 * G) + (0.439 * B) + 128 );
Cr := Round( (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 );
{y := Round(0.299*R + 0.587*G + 0.114*B);
Cb := Round(0.564*(B - Y ));
Cr := Round(0.713*(R - Y )) }
end;
function YUVtoColor(Y, Cb, Cr: Byte): TColor;
{
Lum (Y) ranges from 16 to 235.
Cb (U) ranges from 16 to 240.
Cr (V) ranges from 16 to 240.
}
var
R,G,B: Byte;
begin
G := Round( (1.164 * (Y-16)) - (0.391 * (Cb-128)) - (0.813 * (Cr-128)) );
R := Round( (1.164 * (Y-16)) + (1.596 * (Cr-128)) );
B := Round( (1.164 * (Y-16)) + (2.018 * (Cb-128)) ); Result := RGBToColor(R, G, B);
end;
end.
//YUVBuf是YUV2的数据指针,RGBBuf是输出RGB数据的地址指针,RGBBuf必须在调用
//本函数前提前申请好足够多的内存空间,W和H是宽高
procedure YUV2RGB24(YUVBuf:pointer; RGBBuf:Pointer; W, H:integer);
function trunc1(Value:integer):word;
begin
if Value < 0 then
result := 0
else if Value > $FF00 then
result := $FF00
else result := Value;
end;
var n1,n2,n3:integer;
i,j,k,m : integer;
Y, U, V : Byte;
RGBBuf1 : pointer;
begin
for i := H downto 1 do
begin
RGBBuf1 := pointer(longint(RGBBuf)+ (H - i)* W * 3);
k := 0; j := 0;
for m := 0 to W div 2 - 1 do
begin
y := Pbyte(longint(YUVBuf) +k+0)^;
u := Pbyte(longint(YUVBuf) +k+1)^;
v := Pbyte(longint(YUVBuf) +k+3)^;
n1:= 511 * u - 6 * v - 64522;
n2:= 48838 - 125 * u - 255 * v;
n3:= 506 * v - 64522 - u;
PByte(longint(RGBBuf1)+ j )^ := Trunc1((y shl 8) + n1) shr 8;
PByte(longint(RGBBuf1)+ j + 1)^ := Trunc1((y shl 8) + n2) shr 8;
PByte(longint(RGBBuf1)+ j + 2)^ := Trunc1((y shl 8) + n3) shr 8;
y := Pbyte(longint(YUVBuf) +k+2)^;
PByte(longint(RGBBuf1)+ j +3)^ := Trunc1((y shl 8) + n1) shr 8;
PByte(longint(RGBBuf1)+ j +4)^ := Trunc1((y shl 8) + n2) shr 8;
PByte(longint(RGBBuf1)+ j +5)^ := Trunc1((y shl 8) + n3) shr 8; k := k + 4;
j := j + 6;
end;
YUVBuf := pointer(longint(YUVBuf)+ W * 2);
end;
end;