Delphi之BitBlt函数与屏幕截屏

BitBlt函数的功能是:把源设备的矩形放到目标设备中。让我们来看下函数原型

BOOL BitBlt(

    HDC hdcDest,	// handle to destination device context 
    int nXDest,	// x-coordinate of destination rectangle's upper-left corner
    int nYDest,	// y-coordinate of destination rectangle's upper-left corner
    int nWidth,	// width of destination rectangle 
    int nHeight,	// height of destination rectangle 
    HDC hdcSrc,	// handle to source device context 
    int nXSrc,	// x-coordinate of source rectangle's upper-left corner  
    int nYSrc,	// y-coordinate of source rectangle's upper-left corner
    DWORD dwRop 	// raster operation code 
   );

hdcDest 就是目标设备句柄

nXDest 目标设备的X

nYDest 目标设备的Y

nWidth 目标设备的宽

nHeight 目标设备的高

hdcSrc 源设备句柄

nXSrc 源矩形的起始x

nYSrc 源矩形的起始y

dwRop 光栅操作码, 也就是源像素与目标像素的混合方式

下面是所有的操作码,没错都是英文的,等有功夫我再翻译过来,这里就先翻译两个我现在要用到的。是SRCCOPY。

值       说明

SRCCOPY   把源矩形直接复制到目标矩形中
BLACKNESS    Fills the destination rectangle using the color associated with index 0 in the physical palette. (This color is black for the default physical palette.)
DSTINVERT    Inverts the destination rectangle.
MERGECOPY    Merges the colors of the source rectangle with the specified pattern by using the Boolean AND operator.
MERGEPAINT    Merges the colors of the inverted source rectangle with the colors of the destination rectangle by using the Boolean OR operator.
NOTSRCCOPY    Copies the inverted source rectangle to the destination.
NOTSRCERASE    Combines the colors of the source and destination rectangles by using the Boolean OR operator and then inverts the resultant color.
PATCOPY    Copies the specified pattern into the destination bitmap.
PATINVERT    Combines the colors of the specified pattern with the colors of the destination rectangle by using the Boolean XOR operator.
PATPAINT    Combines the colors of the pattern with the colors of the inverted source rectangle by using the Boolean OR operator. The result of this operation is combined with the colors of the destination rectangle by using the Boolean OR operator.
SRCAND    Combines the colors of the source and destination rectangles by using the Boolean AND operator.

SRCERASE    Combines the inverted colors of the destination rectangle with the colors of the source rectangle by using the Boolean AND operator.
SRCINVERT    Combines the colors of the source and destination rectangles by using the Boolean XOR operator.
SRCPAINT    Combines the colors of the source and destination rectangles by using the Boolean OR operator.
WHITENESS    Fills the destination rectangle using the color associated with index 1 in the physical palette. (This color is white for the default physical palette.)

 

下面是截屏代码,如果有些函数或者结构体难理解的 我会再开一篇文章专门记录,以便自己可以查询使用

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;
const
  ALPHA_SCREEN       = 255;                     { 背景ALPHA值    }
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    FBF: TBlendFunction;                        { Alpha  TBlendFunction结构    }
    FScreenBitMap:TBitmap;
    procedure SetAlpha(const ARect: TRect;                      { 设置透明     }
                       const AlphaValue: Byte = 255);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
const
  CAPTUREBLT = $40000000;
var
  LDC:HDC;//源句柄
begin
  FormStyle:=fsStayOnTop;//窗体始终位于最前面
  BorderStyle:=bsNone;//窗体无边框
  WindowState:=wsMaximized;//窗体最大化
  Color:=clBlack;//设置窗体背景颜色为黑色
  FScreenBitMap:=TBitMap.Create;//创建原图
  BoundsRect := Screen.DesktopRect;  //BoundsRect就是一个Rect 后面是获取桌面的Rect

  //获取桌面图
  LDC:=GetDC(GetDesktopWindow);//获取桌面句柄
  FScreenBitMap.Width:=Width;//和桌面宽度一样 这里后面的Width是窗口宽,但是窗口最大化了所以是桌面宽
  FScreenBitMap.Height:=Height;//和桌面高度一样
  BitBlt(FScreenBitMap.Canvas.Handle,0,0,Width,Height,LDC,0,0,SRCCOPY or CAPTUREBLT);
  ReleaseDC(Handle,LDC);
end;

procedure TForm1.SetAlpha(const ARect: TRect; const AlphaValue: Byte = 255);
begin
  with FBF do
  begin
    BlendOp := AC_SRC_OVER;
    BlendFlags := 0;                     {        0       }
    SourceConstantAlpha := AlphaValue;   { 透明度: 0..255 }
    AlphaFormat := 0;
  end;
  with ARect do
    Windows.AlphaBlend(Canvas.Handle,
                       Left, Top, Right - Left, Bottom - Top,
                       FScreenBitMap.Canvas.Handle,
                       Left, Top, Right - Left, Bottom - Top,
                       FBF);
(*
AlphaBled原型
BOOL AlphaBlend(
    HDC   hdcDest,
    int     nXOriginDest,  int   nYOriginDest,  int   nWidthDest,  int   nHeightDest,
    HDC   hdcSrc,
    int     nXOriginSrc,    int   nYOriginSrc,    int   nWidthSrc,   int   nHeightSrc,
    BLENDFUNCTION  blendFunction
    );
这前面的和BitBlt一样 都是目标DC和源DC和他们的位置宽高,最后一个是混合函数,混合函数是上面的FBF,已经赋值好了 FBF 的结构 以及注释如下*)
  (*
  TBlendFunction = _BLENDFUNCTION;
_BLENDFUNCTION = packed record
    BlendOp: BYTE;//指定源混合操作,目前,唯一的源和目标的混合方式已定义为AC_SRC_OVER
    BlendFlags: BYTE;//必须是0
    SourceConstantAlpha: BYTE;//指定一个alpha透明度值,这个值将用于整个源位图;该SourceConstantAlpha值与源位图的每个像素的alpha值组合;如果设置为0,就会假定你的图片是透明的;如果需要使用每像素本身的alpha值,设置SourceConstantAlpha值255(不透明)
    AlphaFormat: BYTE;//这个参数控制源和目标的解析方式,AlphaFormat参数有以下值:
    AC_SRC_ALPHA:这个值在源或者目标本身有Alpha通道时(也就是操作的图本身带有透明通道信息时),提醒系统API调用函数必须预先乘以alpha值,
    也就是说位图上某个像素位置的red、green、blue通道值必须先与alpha相乘。例如,如果alpha透明值是x,那么red、green、blue三个通道的值
    必须乘以x并且再除以255(因为alpha的值的范围时0~255),之后才能被调用。
    备注:
    1.当AlphaFormat参数的值是AC_SRC_ALPHA,那么源位图必须是32位深,否则的话,AlphaBland函数将调用失败
    2.当BlendOp参数是AC_SRC_OVER时,源位图根据alpha透明度值直接覆盖在目标位图之上
    3.如果源位图不带有透明度信息(那样的话,AC_SRC_ALPHA不设置),将由SourceConstantAplha的值来决定如何混合源位图与目标位图
    4.如果源位图没有用SourceConstantAlpha参数值(那表示该参数等于255),每一个像素的透明度将决定源位图和目标位图的混合结果
    5.如果源位图既有SourceConstantAlpha值(也就是它的值不是255),每个像素又有透明度值,那么源位图的每一个像素将首先乘以
    SourceConstantAlpha的值,然后根据每个像素的透明度值混合。
  end;
  *)

end;
procedure TForm1.FormPaint(Sender: TObject);
begin
  SetAlpha(BoundsRect, ALPHA_SCREEN);
end;

end.

对于上面透明的这个函数有一个很好的帖子可以看下,下面贴上地址

https://blog.csdn.net/iteye_6637/article/details/82536081

运行之后,桌面图像就被放到窗口里了 如果想要保存或者其他,可以去放到Image 再把Image另存为什么都行,不再过多赘述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Windows API中的BitBlt函数进行屏幕截图并保存。 具体步骤如下: 1. 获取屏幕的设备上下文(HDC),可以使用GetDC函数获取整个屏幕的设备上下文,也可以使用CreateDC函数获取指定显示器的设备上下文。 2. 创建一个和屏幕设备上下文相同的内存设备上下文(HDC),可以使用CreateCompatibleDC函数创建。 3. 创建一个和屏幕大小相同的位图对象(HBITMAP),可以使用CreateCompatibleBitmap函数创建。 4. 将位图对象选入内存设备上下文中,可以使用SelectObject函数。 5. 使用BitBlt函数屏幕内容复制到内存设备上下文中的位图对象中。 6. 将位图对象保存为文件,可以使用SaveHBITMAPToFile函数。 7. 释放所有资源,包括设备上下文、位图对象和内存设备上下文,可以使用ReleaseDC函数、DeleteObject函数和DeleteDC函数。 以下是一个示例代码: ``` #include <Windows.h> void SaveHBITMAPToFile(HBITMAP hBitmap, LPCTSTR lpFileName) { BITMAP bmp; GetObject(hBitmap, sizeof(bmp), &bmp); BITMAPFILEHEADER bfh; bfh.bfType = 0x4D42; // "BM" bfh.bfSize = sizeof(bfh) + sizeof(BITMAPINFOHEADER) + bmp.bmWidthBytes * bmp.bmHeight; bfh.bfReserved1 = 0; bfh.bfReserved2 = 0; bfh.bfOffBits = sizeof(bfh) + sizeof(BITMAPINFOHEADER); BITMAPINFOHEADER bih; bih.biSize = sizeof(bih); bih.biWidth = bmp.bmWidth; bih.biHeight = bmp.bmHeight; bih.biPlanes = 1; bih.biBitCount = 24; bih.biCompression = BI_RGB; bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight; bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; bih.biClrUsed = 0; bih.biClrImportant = 0; BYTE* pBits = new BYTE[bmp.bmWidthBytes * bmp.bmHeight]; GetBitmapBits(hBitmap, bmp.bmWidthBytes * bmp.bmHeight, pBits); HANDLE hFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { DWORD dwWritten; WriteFile(hFile, &bfh, sizeof(bfh), &dwWritten, NULL); WriteFile(hFile, &bih, sizeof(bih), &dwWritten, NULL); WriteFile(hFile, pBits, bmp.bmWidthBytes * bmp.bmHeight, &dwWritten, NULL); CloseHandle(hFile); } delete[] pBits; } int main() { HDC hdcScreen = GetDC(NULL); HDC hdcMem = CreateCompatibleDC(hdcScreen); HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); SelectObject(hdcMem, hBitmap); BitBlt(hdcMem, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), hdcScreen, 0, 0, SRCCOPY); SaveHBITMAPToFile(hBitmap, TEXT("screenshot.bmp")); ReleaseDC(NULL, hdcScreen); DeleteObject(hBitmap); DeleteDC(hdcMem); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值