各位,海康卡系统编程中,如何将此C语言译为delphi JPG抓图???(200分)

  • 主题发起人 主题发起人 rzqcjwrz
  • 开始时间 开始时间
R

rzqcjwrz

Unregistered / Unconfirmed
GUEST, unregistred user!
//capture jpg picture
if(!imageBuffer)
return;
Size = 704 * 576*2;
int ret=GetJpegImage(ChannelHandle[iLastSelect],imageBuffer,&Size,jpegQuality);
if(ret==0)
{
CString str;
str.Format("ch%02d_%s.jpg",iLastSelect,csStartTime);
FILE *pFile=fopen(str.GetBuffer(0),"wb");
if(pFile)
{
fwrite(imageBuffer,Size,1,pFile);
fclose(pFile);
}
else
AfxMessageBox("Can not open JPEG file!");
}
else if(ret==ERR_OUTOF_MEMORY)
AfxMessageBox("Not enough memory to store bitstream! /n or /n Image is too complex!");
else if(ret==ERR_WAIT_TIMEOUT)
AfxMessageBox("System is too busy!");
delete []imageBuffer;
Sleep(10);
 
void CHKVisionDlg::OnCapimage()
{
// TODO: Add your control notification handler code here
UCHAR imageBuf[704 * 576*2];
DWORD Size = 704 * 576*2;
UCHAR *imageBuffer=new UCHAR[Size];
char fileName[256];
CTime m_StartTime1=CTime::GetCurrentTime();
CString csStartTime=m_StartTime1.Format("%Y%m%d%H%M%S");
int ret;
int jpegQuality=100;

{
//capture BMP picture
TRACE("start original image cap/n");
sprintf(fileName, "ch%02d_%s.bmp", iLastSelect,csStartTime);
GetOriginalImage(ChannelHandle[iLastSelect], imageBuf, &Size);
if(Size == 704 *576 * 2)
SaveYUVToBmpFile(fileName, imageBuf, 704, 576);
else if(Size == 704 * 480* 2)
SaveYUVToBmpFile(fileName, imageBuf, 704, 480);
if(Size == 352 *288 * 2)
SaveYUVToBmpFile(fileName, imageBuf, 352, 288);
else if(Size == 352 * 240* 2)
SaveYUVToBmpFile(fileName, imageBuf, 352, 240);
if(Size == 176 *144 * 2)
SaveYUVToBmpFile(fileName, imageBuf, 176, 144);
else if(Size == 176 * 120* 2)
SaveYUVToBmpFile(fileName, imageBuf, 176, 120);

//capture jpg picture
if(!imageBuffer)
return;
Size = 704 * 576*2;
int ret=GetJpegImage(ChannelHandle[iLastSelect],imageBuffer,&Size,jpegQuality);
if(ret==0)
{
CString str;
str.Format("ch%02d_%s.jpg",iLastSelect,csStartTime);
FILE *pFile=fopen(str.GetBuffer(0),"wb");
if(pFile)
{
fwrite(imageBuffer,Size,1,pFile);
fclose(pFile);
}
else
AfxMessageBox("Can not open JPEG file!");
}
else if(ret==ERR_OUTOF_MEMORY)
AfxMessageBox("Not enough memory to store bitstream! /n or /n Image is too complex!");
else if(ret==ERR_WAIT_TIMEOUT)
AfxMessageBox("System is too busy!");
delete []imageBuffer;
Sleep(10);
}


}
 
var
Size int64;
ret integer;

if(imageBuffer=nil) then exit;
Size = 704 * 576*2;
ret=GetJpegImage(ChannelHandle[iLastSelect],imageBuffer,&Size,jpegQuality);
if(ret==0) then
begin
CString str;
str.Format("ch%02d_%s.jpg",iLastSelect,csStartTime);
FILE *pFile=fopen(str.GetBuffer(0),"wb");
if(pFile) then
begin
fwrite(imageBuffer,Size,1,pFile);
fclose(pFile);
end
else
showmessage("Can not open JPEG file!");
end
else if(ret==ERR_OUTOF_MEMORY) then
showmessage("Not enough memory to store bitstream! /n or /n Image is too complex!")
else if(ret==ERR_WAIT_TIMEOUT) then
showmessage("System is too busy!");
freeMem(imageBuffer); //在哪里使用了New? 你得把那里翻译成'GetMem'
Sleep(10);
 
{
CString str;
str.Format("ch%02d_%s.jpg",iLastSelect,csStartTime);
FILE *pFile=fopen(str.GetBuffer(0),"wb");
if(pFile)
{
fwrite(imageBuffer,Size,1,pFile);
fclose(pFile);
}
关键是如何译这为delphi?
 
提供一组直接将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(y) + 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(y);
Y2 := y^;
Inc(y);

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;
 
pihome:谢谢你提供的转换函数.
 
var
str: String;
iLastSelect: integer;
csStartTime: string;
pFile: File;
imageBuffer: array of char; //这行需要删除
begin
begin
Format('ch%02d_%s.jpg', [iLastSelect,csStartTime]);
AssignFile(pFile, str); //GetBuffer(0)是干嘛的?
Rewrite(pFile);
BlockWrite(pFile, imageBuffer, 1);
CloseFile(pFile);
end;
end;
 
我试了,告诉你结果.
 
用不着翻译吧,编译成dll使用就可以了。
 
procedure TDvr_Main.GraspVideoPictureJPG(ChannelHandle: Longint; FileName: PChar); //JPG抓图
var
ImgSize : integer;
imageBuf : array[1..704 * 576 * 2] of byte;
ret,jpegQuality:integer;
pFile: File;
begin
if ChannelHandle=-1 then
Exit;
ImgSize:=704*576*2;
jpegQuality:=100;
ret:=GetJpegImage(ChannelHandle,@imageBuf,@ImgSize,jpegQuality);
if(ret=0) then
begin
AssignFile(pFile,FileName );
Rewrite(pFile,imgsize);
BlockWrite(pFile, imageBuf,1);
CloseFile(pFile);
end
end;


procedure TDvr_Main.Dvr_CaptureBtnClick(Sender: TObject);//视频截图
begin
if sel <> -1 then
begin
//文件目录
FilePath := FormatDateTime('yyyymmdd', Date) + '/';
//文件名
FileName := FormatDateTime('hhmmnn', Current_Time);
//通道信息
hChannelHandle[sel] :=sel+1;

//根目录
RootPath := 'd:/视频截图/';
NowPath := RootPath + FilePath+inttostr(hChannelHandle[sel])+'路'+'/' ;
ForceDirectories(NowPath);
// NowName := NowPath+FileName+'.BMP';
NowName := NowPath+FileName+'.jpg';
// GraspVideoPicture(sel, Pchar(NowName));
GraspVideoPictureJPG(sel, Pchar(NowName));
//提示信息
VideoRecord.Panels[3].Text := '第'+inttostr(hChannelHandle[sel])+'路'+ '图片已截取';
end
else
begin
//提示信息
VideoRecord.Panels[3].Text := '请选择摄像机';
end;
end;
 
多人接受答案了。
 
后退
顶部