📄 capframe.~pas
字号:
DC: HDC;
begin
if hPal = 0 then exit;
DC := GetDC(hForm);
try
SelectPalette(DC, hPal, False);
RealizePalette(DC);
finally
ReleaseDC(hForm, DC);
end;
end;
procedure TfamCapture.DelPallete(hPal: HPalette);
begin
if hPal = 0 then exit;
DeleteObject(hPal);
end;
procedure TfamCapture.GetDeskColor(var DeskColor: Word);
var
h: HWND;
DC: HDC;
begin
h := GetDesktopWindow();
DC := GetDC(h);
DeskColor := GetDeviceCaps(DC, BITSPIXEL);
ReleaseDC(h, DC);
end;
procedure TfamCapture.btnSaveFromMemClick(Sender: TObject);
var
pBuf: Pchar;
BufLength: Dword;
BlockSize, PhysMemAdrr, MemHandle, LineAddr: Dword;
pBMIInfo: PBITMAPINFO;
//采集到内存中的图像数
Sum: DWORD;
//控制回放次数
i: integer;
Bmp: TBitmap;
begin
if hcg < 4 then exit;
//停止播放
StopCapture();
//重新设置窗口
AdjustWndPos();
//使用控制面版中分派的静态内存保存图象
if (StaticMemAlloc(BlockSize, PhysMemAdrr, MemHandle, LineAddr)<>1) then
begin
ShowMessage('访问静态保留内存失败!');
exit;
end;
//动态分配Buf的大小是多少字节
Case ColorSpace of
RGB888 :
BufLength := 768 * 576 * 3;
RGB565 :
BufLength := 768 * 576 * 3;
RGB555 :
BufLength := 768 * 576 * 3;
RGB8888 :
BufLength := 768 * 576 * 4;
All8Bit :
BufLength := 768 * 576 * 1;
Limited8Bit :
BufLength := 768 * 576 * 1;
else
BufLength := 768 * 576 * 4;
end;
//分配帧缓存
pBuf := AllocMem(BufLength);
pBMIInfo := AllocMem(sizeof(TBITMAPINFO)+ (255 * sizeof(TRGBQuad)));
Bmp := TBitmap.Create;
try
bmp.Width:= VideoPanel.Width;
bmp.Height := VideoPanel.Height;
//设定BMP的头信息
pBMIInfo^.bmiHeader.biSize := sizeof(BITMAPINFOHEADER);
pBMIInfo^.bmiHeader.biWidth := VideoPanel.Width;
pBMIInfo^.bmiHeader.biHeight := VideoPanel.Height;
pBMIInfo^.bmiHeader.biPlanes := 1;
if (ColorSpace = All8Bit)or(ColorSpace = Limited8Bit) then
begin
pBMIInfo^.bmiHeader.biBitCount := 8;
for i :=0 to 255 do
begin
pBMIInfo^.bmiColors[i].rgbBlue := i;
pBMIInfo^.bmiColors[i].rgbGreen := i;
pBMIInfo^.bmiColors[i].rgbRed := i;
pBMIInfo^.bmiColors[i].rgbReserved := 0;
end;
Bmp.PixelFormat := pf8bit;
Bmp.Palette := hPal;
end
else
begin
pBMIInfo^.bmiHeader.biBitCount := 24;
Bmp.PixelFormat := pf24bit;
end;
pBMIInfo^.bmiHeader.biCompression := BI_RGB;
pBMIInfo^.bmiHeader.biSizeImage := 0;
pBMIInfo^.bmiHeader.biXPelsPerMeter := 0;
pBMIInfo^.bmiHeader.biYPelsPerMeter := 0;
pBMIInfo^.bmiHeader.biClrUsed := 0;
pBMIInfo^.bmiHeader.biClrImportant := 0;
//控制面版中分派的静态内存可以保存当前尺寸的采集图象的总数SUM
case ColorSpace of
RGB888 : Sum := (BlockSize * 1024 * 4) div Dword(VideoPanel.Width * VideoPanel.Height * 3);
RGB565 : Sum := (BlockSize * 1024 * 4) div Dword(VideoPanel.Width * VideoPanel.Height * 2);
RGB555 : Sum := (BlockSize * 1024 * 4) div Dword(VideoPanel.Width * VideoPanel.Height * 2);
RGB8888 : Sum := (BlockSize * 1024 * 4) div Dword(VideoPanel.Width * VideoPanel.Height * 4);
All8Bit : Sum := (BlockSize * 1024 * 4) div Dword(VideoPanel.Width * VideoPanel.Height);
Limited8Bit :Sum := (BlockSize * 1024 * 4) div Dword(VideoPanel.Width * VideoPanel.Height);
else
Sum := 0;
end;
//采集到内存中
Sum :=CG300CaptureToMem(hcg, PhysMemAdrr, BlockSize * 1024 * 4, 0, FRAME, Sum);
// PlayBack播放十次
for i := 1 to Sum do
begin
//从内存中读取一图
CG300ReadfromMem(hcg, Pchar(LineAddr), BlockSize * 1024 * 4, i - 1, pBuf);
//调用win32的API函数将Buf中的数据以图象形式显示在VideoPanel上
SetStretchBltMode(Bmp.Canvas.Handle, COLORONCOLOR);
SetDIBitsToDevice(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height,
0, 0, 0, pBMIInfo^.bmiHeader.biHeight,
pBuf, pBMIInfo^, DIB_RGB_COLORS);
Bmp.SaveToFile(IntToStr(i)+'.bmp');
//提示一共采集到内存中的图象数
end;
Application.MessageBox(pchar('共有' + IntToStr(Sum) + '帧图象保存为BMP文件!'),
'提示', MB_OK);
finally
//释放内存
Bmp.Free;
FreeMem(pBMIInfo, sizeof(TBITMAPINFO)+ (255 * sizeof(TRGBQuad)));
FreeMem(pBuf, BufLength);
end;
end;
//演示SnapToMem多缓存采集显示,SnapToMem类似SnapOneToMem,但是
//可以缓冲区不再局限为2帧,用户可以自行设定缓冲区的帧数。
procedure TfamCapture.ToolButton1Click(Sender: TObject);
var
nStatus: integer; //采集状态,完成还是没有
BufLength: Dword; //buf大小为多少字节
pBuf: Pchar;//帧缓存指针
BlockSize, PhysMemAdrr, MemHandle, LineAddr: Dword; //内存参数
pBMIInfo: PBITMAPINFO;
VideoDc: HDC;
i: integer;
begin
if hcg < 4 then Exit;
//停止采集
StopCapture();
// 动态分配Buf的大小是多少字节,由于按当前显示的图象大小 //
// 保存,且DLL中函数一定要求以24Bit保存,即每像素3字节, //
// 所以用到的buf大小应该是paintbox.Width*PaintBox.Height*3 //
// 但是如果用户在sanpone的过程动态改变了程序窗体大小有可能 //
// 造成buf的空间过小使得操作内存出错,为了安全buf设置为最大//
// 即(768*576*3)表示768*576像素,每个像素是32bit //
Case ColorSpace of
RGB888 :
BufLength := 768 * 576 * 3;
RGB565 :
BufLength := 768 * 576 * 3;
RGB555 :
BufLength := 768 * 576 * 3;
RGB8888 :
BufLength := 768 * 576 * 4;
All8Bit :
BufLength := 768 * 576 * 1;
Limited8Bit :
BufLength := 768 * 576 * 1;
else
BufLength := 768 * 576 * 4;
end;
//使用控制面版中分派的静态内存保存图象
StaticMemAlloc(BlockSize, PhysMemAdrr, MemHandle, LineAddr);
//检测静态内存是否够用,静态内存应该为两个BufLength大小
if (BlockSize * 4096) > (BufLength*2) then
begin
//更改按钮状态
btnFreeze.Enabled := True;
btnSnapOne.Enabled := False;
btnLive.Enabled := False;
btnSetup.Enabled := False;
btnPlayBack.Enabled := False;
btnSaveFromMem.Enabled := False;
//切换SanpOne状态控制
isSnapOne := True;
//重新设置窗口
self.AdjustWndPos;
VideoDc := GetDc(VideoPanel.Handle);
//分配帧缓存
pBuf := AllocMem(BufLength);
pBMIInfo := AllocMem(sizeof(TBITMAPINFO)+ (255 * sizeof(TRGBQuad)));
try
//设定BMP的头信息
pBMIInfo^.bmiHeader.biSize := sizeof(BITMAPINFOHEADER);
pBMIInfo^.bmiHeader.biWidth := VideoPanel.Width;
pBMIInfo^.bmiHeader.biHeight := VideoPanel.Height;
pBMIInfo^.bmiHeader.biPlanes := 1;
if (ColorSpace = All8Bit)or(ColorSpace = Limited8Bit) then
begin
pBMIInfo^.bmiHeader.biBitCount := 8;
for i :=0 to 255 do
begin
pBMIInfo^.bmiColors[i].rgbBlue := i;
pBMIInfo^.bmiColors[i].rgbGreen := i;
pBMIInfo^.bmiColors[i].rgbRed := i;
pBMIInfo^.bmiColors[i].rgbReserved := 0;
end;
end
else
pBMIInfo^.bmiHeader.biBitCount := 24;
pBMIInfo^.bmiHeader.biCompression := BI_RGB;
pBMIInfo^.bmiHeader.biSizeImage := 0;
pBMIInfo^.bmiHeader.biXPelsPerMeter := 0;
pBMIInfo^.bmiHeader.biYPelsPerMeter := 0;
pBMIInfo^.bmiHeader.biClrUsed := 0;
pBMIInfo^.bmiHeader.biClrImportant := 0;
if (ColorSpace = All8Bit)or(ColorSpace = Limited8Bit) then
begin
end;
//开始启动SnapToMem采集设定缓冲区为2帧图像大小
CG300SnapToMem(hcg, PhysMemAdrr, BlockSize * 4096, FRAME, 2);
nStatus := 1;
SetStretchBltMode(VideoDC, COLORONCOLOR);
while isSnapOne do
begin
Application.ProcessMessages;
//不断得到图像的采集状态
CG300GetSnapToMemNumber(hcg, nStatus);
if nstatus = 2 then //采集完成
begin
//Num:=1;
//CG300ReadfromMem(hcg, Pchar(LineAddr), BlockSize * 1024 * 4,Num-1, pBuf);
CG300CopyFromMem(hcg, pBuf, Pchar(LineAddr), VideoPanel.Width*VideoPanel.Height*3);
end;
if nstatus = 0 then //采集完成
begin
//Num:=2;
//CG300ReadfromMem(hcg, Pchar(LineAddr), BlockSize * 1024 * 4,Num-1, pBuf);
CG300CopyFromMem(hcg, pBuf, Pchar(LineAddr+DWORD(VideoPanel.Width*VideoPanel.Height*3)), VideoPanel.Width*VideoPanel.Height*3);
end;
//8位数据使用调色板
if (ColorSpace = All8Bit)or(ColorSpace = Limited8Bit) then
begin
SelectPalette(VideoDC, hPal, False);
RealizePalette(VideoDC);
end;
//显示图像
StretchDIBits(VideoDC, 0, 0, VideoPanel.Width, VideoPanel.Height,
0, 0, pBMIInfo^.bmiHeader.biWidth, pBMIInfo^.bmiHeader.biHeight,
pBuf, pBMIInfo^, DIB_RGB_COLORS, SRCCOPY);
end;
finally
//释放内存
FreeMem(pBMIInfo, sizeof(TBITMAPINFO)+ (255 * sizeof(TRGBQuad)));
FreeMem(pBuf, BufLength);
ReleaseDC(VideoPanel.Handle, VideoDC);
end;
end
else
begin
Application.MessageBox('调用控制面版中分派的静态内存失败,停止抓图!', '提示', MB_OK);
end;
end;
//重新设定静态内存的大小,需要重新启动系统,这里是设置了2048*4K大小的内存。
procedure TfamCapture.ToolButton3Click(Sender: TObject);
begin
if SetStaticMemAlloc(2048)=1 then ShowMessage('Set Mem OK!');
end;
function TfamCapture.GetOneBmp: TBitmap;
var
pBuf: Pchar;
BufLength: Dword;
BlockSize, PhysMemAdrr, MemHandle, LineAddr: Dword;
pBMIInfo: PBITMAPINFO;
//采集到内存中的图像数
Sum: DWORD;
//控制回放次数
i: integer;
Bmp: TBitmap;
begin
if hcg < 4 then exit;
//停止播放
StopCapture();
//重新设置窗口
AdjustWndPos();
//使用控制面版中分派的静态内存保存图象
if (StaticMemAlloc(BlockSize, PhysMemAdrr, MemHandle, LineAddr)<>1) then
begin
ShowMessage('访问静态保留内存失败!');
exit;
end;
//动态分配Buf的大小是多少字节
Case ColorSpace of
RGB888 :
BufLength := 768 * 576 * 3;
RGB565 :
BufLength := 768 * 576 * 3;
RGB555 :
BufLength := 768 * 576 * 3;
RGB8888 :
BufLength := 768 * 576 * 4;
All8Bit :
BufLength := 768 * 576 * 1;
Limited8Bit :
BufLength := 768 * 576 * 1;
else
BufLength := 768 * 576 * 4;
end;
//分配帧缓存
pBuf := AllocMem(BufLength);
pBMIInfo := AllocMem(sizeof(TBITMAPINFO)+ (255 * sizeof(TRGBQuad)));
Bmp := TBitmap.Create;
try
bmp.Width:= VideoPanel.Width;
bmp.Height := VideoPanel.Height;
//设定BMP的头信息
pBMIInfo^.bmiHeader.biSize := sizeof(BITMAPINFOHEADER);
pBMIInfo^.bmiHeader.biWidth := VideoPanel.Width;
pBMIInfo^.bmiHeader.biHeight := VideoPanel.Height;
pBMIInfo^.bmiHeader.biPlanes := 1;
if (ColorSpace = All8Bit)or(ColorSpace = Limited8Bit) then
begin
pBMIInfo^.bmiHeader.biBitCount := 8;
for i :=0 to 255 do
begin
pBMIInfo^.bmiColors[i].rgbBlue := i;
pBMIInfo^.bmiColors[i].rgbGreen := i;
pBMIInfo^.bmiColors[i].rgbRed := i;
pBMIInfo^.bmiColors[i].rgbReserved := 0;
end;
Bmp.PixelFormat := pf8bit;
Bmp.Palette := hPal;
end
else
begin
pBMIInfo^.bmiHeader.biBitCount := 24;
Bmp.PixelFormat := pf24bit;
end;
pBMIInfo^.bmiHeader.biCompression := BI_RGB;
pBMIInfo^.bmiHeader.biSizeImage := 0;
pBMIInfo^.bmiHeader.biXPelsPerMeter := 0;
pBMIInfo^.bmiHeader.biYPelsPerMeter := 0;
pBMIInfo^.bmiHeader.biClrUsed := 0;
pBMIInfo^.bmiHeader.biClrImportant := 0;
//采集一副图象
sum := 1;
//采集到内存中
Sum :=CG300CaptureToMem(hcg, PhysMemAdrr, BlockSize * 1024 * 4, 0, FRAME, Sum);
if Sum > 0 then
begin
CG300ReadfromMem(hcg, Pchar(LineAddr), BlockSize * 1024 * 4, i - 1, pBuf);
SetStretchBltMode(Bmp.Canvas.Handle, COLORONCOLOR);
SetDIBitsToDevice(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height,
0, 0, 0, pBMIInfo^.bmiHeader.biHeight,
pBuf, pBMIInfo^, DIB_RGB_COLORS);
Result := Bmp;
end
else begin
Bmp.Free;
Result := nil ;
end;
{// PlayBack播放十次
for i := 1 to Sum do
begin
//从内存中读取一图
CG300ReadfromMem(hcg, Pchar(LineAddr), BlockSize * 1024 * 4, i - 1, pBuf);
//调用win32的API函数将Buf中的数据以图象形式显示在VideoPanel上
SetStretchBltMode(Bmp.Canvas.Handle, COLORONCOLOR);
SetDIBitsToDevice(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height,
0, 0, 0, pBMIInfo^.bmiHeader.biHeight,
pBuf, pBMIInfo^, DIB_RGB_COLORS);
Bmp.SaveToFile(IntToStr(i)+'.bmp');
//提示一共采集到内存中的图象数
end;}
finally
//释放内存
//Bmp.Free;
FreeMem(pBMIInfo, sizeof(TBITMAPINFO)+ (255 * sizeof(TRGBQuad)));
FreeMem(pBuf, BufLength);
end;
//在开始播放
BeginCapture();
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -