## 这里是复制bmp图片内存对象
# 加载必要的 Windows API 函数
user32_1 = ctypes.windll.user32
kernel32_1 = ctypes.windll.kernel32
# 定义常量
CF_BITMAP = 2
# 打开剪贴板
def OpenClipboard(hwnd):
return user32_1.OpenClipboard(hwnd)
# 关闭剪贴板
def CloseClipboard():
return user32_1.CloseClipboard()
# 清空剪贴板
def EmptyClipboard():
return user32_1.EmptyClipboard()
# 设置剪贴板数据
def SetClipboardData(uFormat, hData):
return user32_1.SetClipboardData(uFormat, hData)
# 全局分配内存
def GlobalAlloc(uFlags, dwBytes):
return kernel32_1.GlobalAlloc(uFlags, dwBytes)
# 全局锁定内存
def GlobalLock(hMem):
return kernel32_1.GlobalLock(hMem)
# 全局解锁内存
def GlobalUnlock(hMem):
return kernel32_1.GlobalUnlock(hMem)
# 将图片复制到剪贴板
def copy_bmp_to_clipboard():
hwnd = 0 # 可以传递 NULL(0)作为 hwnd
if OpenClipboard(hwnd):
try:
EmptyClipboard()
SetClipboardData(CF_BITMAP, bmp) # CF_BITMAP = 2
finally:
CloseClipboard()
copy_bmp_to_clipboard()
## 这里是复制bmp图片内存对象
# 加载必要的 Windows API 函数
user32_1 = ctypes.windll.user32
kernel32_1 = ctypes.windll.kernel32
# 定义常量
CF_BITMAP = 2
# 打开剪贴板
def OpenClipboard(hwnd):
return user32_1.OpenClipboard(hwnd)
# 关闭剪贴板
def CloseClipboard():
return user32_1.CloseClipboard()
# 清空剪贴板
def EmptyClipboard():
return user32_1.EmptyClipboard()
# 设置剪贴板数据
def SetClipboardData(uFormat, hData):
return user32_1.SetClipboardData(uFormat, hData)
# 全局分配内存
def GlobalAlloc(uFlags, dwBytes):
return kernel32_1.GlobalAlloc(uFlags, dwBytes)
# 全局锁定内存
def GlobalLock(hMem):
return kernel32_1.GlobalLock(hMem)
# 全局解锁内存
def GlobalUnlock(hMem):
return kernel32_1.GlobalUnlock(hMem)
# 将图片复制到剪贴板
def copy_bmp_to_clipboard():
hwnd = 0 # 可以传递 NULL(0)作为 hwnd
if OpenClipboard(hwnd):
try:
EmptyClipboard()
SetClipboardData(CF_BITMAP, bmp) # CF_BITMAP = 2
finally:
CloseClipboard()
copy_bmp_to_clipboard()
import ctypes
import zlib
import struct
from ctypes import wintypes, c_int, POINTER, create_string_buffer
import io
import time
s = time.time()
# 加载GDI32和User32库
gdi32 = ctypes.WinDLL('gdi32')
user32 = ctypes.WinDLL('user32')
# 函数参数和返回类型设置
gdi32.BitBlt.argtypes = [wintypes.HDC, c_int, c_int, c_int, c_int, wintypes.HDC, c_int, c_int, wintypes.DWORD]
gdi32.BitBlt.restype = wintypes.BOOL
user32.GetDesktopWindow.restype = wintypes.HWND
user32.GetDC.argtypes = [wintypes.HWND]
user32.GetDC.restype = wintypes.HDC
user32.ReleaseDC.argtypes = [wintypes.HWND, wintypes.HDC]
user32.ReleaseDC.restype = wintypes.BOOL
# 定义常量
SM_CXSCREEN = 0
SM_CYSCREEN = 1
# 缩放比例
zoom = 1
screenWidth = int(user32.GetSystemMetrics(SM_CXSCREEN) * zoom)
screenHeight = int(user32.GetSystemMetrics(SM_CYSCREEN) * zoom)
# 屏幕截取
def capture_screen(x, y, width, height):
# 获取桌面窗口句柄
hwnd = user32.GetDesktopWindow()
print(hwnd)
# 获取桌面窗口的设备上下文
hdc_src = user32.GetDC(hwnd)
print(hdc_src)
if len(str(hdc_src)) > 16:
return 0
# 创建一个与屏幕兼容的内存设备上下文
hdc_dest = gdi32.CreateCompatibleDC(hdc_src)
# 创建一个位图
bmp = gdi32.CreateCompatibleBitmap(hdc_src, width, height)
# # 将位图选入内存设备上下文
old_bmp = gdi32.SelectObject(hdc_dest, bmp)
# 定义SRCCOPY常量
SRCCOPY = 0x00CC0020
# 捕获屏幕
gdi32.BitBlt(hdc_dest, 0, 0, width, height, hdc_src, x, y, SRCCOPY)
"""
gdi32.BitBlt(hdc_src, # 目标设备上下文
x_dest, # 目标矩形左上角的x坐标
y_dest, # 目标矩形左上角的y坐标
width, # 宽度
height, # 高度
hdc_dest, # 源设备上下文
x_src, # 源矩形左上角的x坐标(通常是0)
y_src, # 源矩形左上角的y坐标(通常是0)
SRCCOPY) # 复制选项
"""
## 这里是复制bmp图片内存对象
# 加载必要的 Windows API 函数
user32_1 = ctypes.windll.user32
kernel32_1 = ctypes.windll.kernel32
# 定义常量
CF_BITMAP = 2
# 打开剪贴板
def OpenClipboard(hwnd):
return user32_1.OpenClipboard(hwnd)
# 关闭剪贴板
def CloseClipboard():
return user32_1.CloseClipboard()
# 清空剪贴板
def EmptyClipboard():
return user32_1.EmptyClipboard()
# 设置剪贴板数据
def SetClipboardData(uFormat, hData):
return user32_1.SetClipboardData(uFormat, hData)
# 全局分配内存
def GlobalAlloc(uFlags, dwBytes):
return kernel32_1.GlobalAlloc(uFlags, dwBytes)
# 全局锁定内存
def GlobalLock(hMem):
return kernel32_1.GlobalLock(hMem)
# 全局解锁内存
def GlobalUnlock(hMem):
return kernel32_1.GlobalUnlock(hMem)
# 将图片复制到剪贴板
def copy_bmp_to_clipboard():
hwnd = 0 # 可以传递 NULL(0)作为 hwnd
if OpenClipboard(hwnd):
try:
EmptyClipboard()
SetClipboardData(CF_BITMAP, bmp) # CF_BITMAP = 2
finally:
CloseClipboard()
copy_bmp_to_clipboard()
# 定义 RGBQUAD 结构体
class RGBQUAD(ctypes.Structure):
_fields_ = [("rgbBlue", ctypes.c_ubyte),
("rgbGreen", ctypes.c_ubyte),
("rgbRed", ctypes.c_ubyte),
("rgbReserved", ctypes.c_ubyte)]
# 定义 BITMAPINFOHEADER 结构体
class BITMAPINFOHEADER(ctypes.Structure):
_fields_ = [("biSize", ctypes.c_uint),
("biWidth", ctypes.c_int),
("biHeight", ctypes.c_int),
("biPlanes", ctypes.c_ushort),
("biBitCount", ctypes.c_ushort),
("biCompression", ctypes.c_uint),
("biSizeImage", ctypes.c_uint),
("biXPelsPerMeter", ctypes.c_int),
("biYPelsPerMeter", ctypes.c_int),
("biClrUsed", ctypes.c_uint),
("biClrImportant", ctypes.c_uint)]
# 定义 BITMAPINFO 结构体
class BITMAPINFO(ctypes.Structure):
_fields_ = [("bmiHeader", BITMAPINFOHEADER),
("bmiColors", RGBQUAD * 3)] # 只分配了3个RGBQUAD的空间
BI_RGB = 0
DIB_RGB_COLORS = 0
# 分配像素数据缓冲区(这里以24位位图为例,每个像素3字节)
pixel_data = (ctypes.c_ubyte * (width * height * 3))() # 4
# 转换bytes
# pixel_data = memoryview(pixel_data).tobytes()
# 填充 BITMAPINFO 结构体
bmi = BITMAPINFO()
bmi.bmiHeader.biSize = ctypes.sizeof(BITMAPINFOHEADER)
bmi.bmiHeader.biWidth = width
bmi.bmiHeader.biHeight = -height # 注意:负高度表示自底向上的位图
bmi.bmiHeader.biPlanes = 1
bmi.bmiHeader.biBitCount = 24 # 24即3*8 32
bmi.bmiHeader.biCompression = BI_RGB # 无压缩
# 调用 GetDIBits 获取像素数据
ret = gdi32.GetDIBits(hdc_src, bmp, 0, height, pixel_data, ctypes.byref(bmi), DIB_RGB_COLORS)
if ret == 0:
print("GetDIBits failed:", ctypes.WinError())
print(time.time() - s)
# 像素色彩换位置
mv = (memoryview(pixel_data).cast('B'))
# b_stream = bytearray(width * (height+1) * 3)
print(len(mv))
b_stream = bytearray()
k=0
# for i in range(0, len(mv), 3):
# if i % (width*3) == 0:
# # b_stream[k] = 0
# k += 1
# b_stream[k] = mv[i + 2]
# b_stream[k + 1] = mv[i + 1]
# b_stream[k + 2] = mv[i]
# k+=3
for i in range(0, len(mv), 3): #4
if i % (width*3) == 0:
b_stream.append(0)
k += 1
b_stream.append(mv[i + 2])
b_stream.append(mv[i + 1])
b_stream.append(mv[i])
# b_stream.extend([mv[i + 2],mv[i + 1],mv[i]])
k+=3
# b_stream.append(mv[i+2])
# b_stream.append(mv[i+1])
# b_stream.append(mv[i+0])
# b_stream.append(mv[i+3])
# k+=4
# print(b_stream)
print(time.time() - s)
def crc32(data): # 字节流
crc = zlib.crc32(data)
return crc
def crc32_b(data):
crc = zlib.crc32(data).to_bytes(4, byteorder='big')
return crc
# png图片标识符
png_signature = b"\x89PNG\r\n\x1a\n"
# IHDR块
ihdr = struct.pack("!IIBBBBB", width, height, 8, 2, 0, 0, 0) # 8 6 0 0 0
# IHDR的CRC验证
mid = crc32_b(b"IHDR" + ihdr)
# 压缩图片数据
bd = zlib.compress(bytes(b_stream))
# IDAT的CRC验证
crc_bytes = crc32_b(bd)
idat_chunk = b"IDAT" + bd + crc_bytes
# IEND块
iend = b"\x00\x00\x00\x00IEND"
# IEND的CRC验证
crc_end = crc32_b(b"IEND")
iend += crc_end
# 写入图片操作,使用BytesIO来构建PNG
png_io = io.BytesIO()
png_io.write(png_signature + b"\x00\x00\x00\rIHDR" + ihdr + mid)
idat_header = struct.pack("!I", len(bd))
png_io.write(idat_header + idat_chunk)
png_io.write(iend)
# 一次性写入文件
with open("photo.png", "wb") as f:
f.write(png_io.getvalue())
# 恢复设备上下文
gdi32.SelectObject(hdc_dest, old_bmp)
# 删除内存设备上下文
gdi32.DeleteDC(hdc_dest)
# 释放桌面窗口的设备上下文
user32.ReleaseDC(hwnd, hdc_src)
# bmp已经被处理,现在删除它
gdi32.DeleteObject(bmp)
# 进行截图
for i in range(10):
x = capture_screen(0, 0, screenWidth, screenHeight)
if x != 0:
break
print(time.time() - s)
import ctypes
import zlib
import struct
from ctypes import wintypes, c_int, POINTER, create_string_buffer
import io
import time
s = time.time()
# 加载GDI32和User32库
gdi32 = ctypes.WinDLL('gdi32')
user32 = ctypes.WinDLL('user32')
# 函数参数和返回类型设置
gdi32.BitBlt.argtypes = [wintypes.HDC, c_int, c_int, c_int, c_int, wintypes.HDC, c_int, c_int, wintypes.DWORD]
gdi32.BitBlt.restype = wintypes.BOOL
user32.GetDesktopWindow.restype = wintypes.HWND
user32.GetDC.argtypes = [wintypes.HWND]
user32.GetDC.restype = wintypes.HDC
user32.ReleaseDC.argtypes = [wintypes.HWND, wintypes.HDC]
user32.ReleaseDC.restype = wintypes.BOOL
# 定义常量
SM_CXSCREEN = 0
SM_CYSCREEN = 1
# 缩放比例
zoom = 1
screenWidth = int(user32.GetSystemMetrics(SM_CXSCREEN) * zoom)
screenHeight = int(user32.GetSystemMetrics(SM_CYSCREEN) * zoom)
# 屏幕截取
def capture_screen(x, y, width, height):
# 获取桌面窗口句柄
hwnd = user32.GetDesktopWindow()
print(hwnd)
# 获取桌面窗口的设备上下文
hdc_src = user32.GetDC(hwnd)
print(hdc_src)
if len(str(hdc_src)) > 16:
return 0
# 创建一个与屏幕兼容的内存设备上下文
hdc_dest = gdi32.CreateCompatibleDC(hdc_src)
# 创建一个位图
bmp = gdi32.CreateCompatibleBitmap(hdc_src, width, height)
# # 将位图选入内存设备上下文
old_bmp = gdi32.SelectObject(hdc_dest, bmp)
# 定义SRCCOPY常量
SRCCOPY = 0x00CC0020
# 捕获屏幕
gdi32.BitBlt(hdc_dest, 0, 0, width, height, hdc_src, x, y, SRCCOPY)
"""
gdi32.BitBlt(hdc_src, # 目标设备上下文
x_dest, # 目标矩形左上角的x坐标
y_dest, # 目标矩形左上角的y坐标
width, # 宽度
height, # 高度
hdc_dest, # 源设备上下文
x_src, # 源矩形左上角的x坐标(通常是0)
y_src, # 源矩形左上角的y坐标(通常是0)
SRCCOPY) # 复制选项
"""
## 这里是复制bmp图片内存对象
# 加载必要的 Windows API 函数
user32_1 = ctypes.windll.user32
kernel32_1 = ctypes.windll.kernel32
# 定义常量
CF_BITMAP = 2
# 打开剪贴板
def OpenClipboard(hwnd):
return user32_1.OpenClipboard(hwnd)
# 关闭剪贴板
def CloseClipboard():
return user32_1.CloseClipboard()
# 清空剪贴板
def EmptyClipboard():
return user32_1.EmptyClipboard()
# 设置剪贴板数据
def SetClipboardData(uFormat, hData):
return user32_1.SetClipboardData(uFormat, hData)
# 全局分配内存
def GlobalAlloc(uFlags, dwBytes):
return kernel32_1.GlobalAlloc(uFlags, dwBytes)
# 全局锁定内存
def GlobalLock(hMem):
return kernel32_1.GlobalLock(hMem)
# 全局解锁内存
def GlobalUnlock(hMem):
return kernel32_1.GlobalUnlock(hMem)
# 将图片复制到剪贴板
def copy_bmp_to_clipboard():
hwnd = 0 # 可以传递 NULL(0)作为 hwnd
if OpenClipboard(hwnd):
try:
EmptyClipboard()
SetClipboardData(CF_BITMAP, bmp) # CF_BITMAP = 2
finally:
CloseClipboard()
copy_bmp_to_clipboard()
# 定义 RGBQUAD 结构体
class RGBQUAD(ctypes.Structure):
_fields_ = [("rgbBlue", ctypes.c_ubyte),
("rgbGreen", ctypes.c_ubyte),
("rgbRed", ctypes.c_ubyte),
("rgbReserved", ctypes.c_ubyte)]
# 定义 BITMAPINFOHEADER 结构体
class BITMAPINFOHEADER(ctypes.Structure):
_fields_ = [("biSize", ctypes.c_uint),
("biWidth", ctypes.c_int),
("biHeight", ctypes.c_int),
("biPlanes", ctypes.c_ushort),
("biBitCount", ctypes.c_ushort),
("biCompression", ctypes.c_uint),
("biSizeImage", ctypes.c_uint),
("biXPelsPerMeter", ctypes.c_int),
("biYPelsPerMeter", ctypes.c_int),
("biClrUsed", ctypes.c_uint),
("biClrImportant", ctypes.c_uint)]
# 定义 BITMAPINFO 结构体
class BITMAPINFO(ctypes.Structure):
_fields_ = [("bmiHeader", BITMAPINFOHEADER),
("bmiColors", RGBQUAD * 3)] # 只分配了3个RGBQUAD的空间
BI_RGB = 0
DIB_RGB_COLORS = 0
# 分配像素数据缓冲区(这里以24位位图为例,每个像素3字节)
pixel_data = (ctypes.c_ubyte * (width * height * 3))() # 4
# 转换bytes
# pixel_data = memoryview(pixel_data).tobytes()
# 填充 BITMAPINFO 结构体
bmi = BITMAPINFO()
bmi.bmiHeader.biSize = ctypes.sizeof(BITMAPINFOHEADER)
bmi.bmiHeader.biWidth = width
bmi.bmiHeader.biHeight = -height # 注意:负高度表示自底向上的位图
bmi.bmiHeader.biPlanes = 1
bmi.bmiHeader.biBitCount = 24 # 24即3*8 32
bmi.bmiHeader.biCompression = BI_RGB # 无压缩
# 调用 GetDIBits 获取像素数据
ret = gdi32.GetDIBits(hdc_src, bmp, 0, height, pixel_data, ctypes.byref(bmi), DIB_RGB_COLORS)
if ret == 0:
print("GetDIBits failed:", ctypes.WinError())
print(time.time() - s)
# 像素色彩换位置
mv = (memoryview(pixel_data).cast('B'))
# b_stream = bytearray(width * (height+1) * 3)
print(len(mv))
b_stream = bytearray()
k=0
# for i in range(0, len(mv), 3):
# if i % (width*3) == 0:
# # b_stream[k] = 0
# k += 1
# b_stream[k] = mv[i + 2]
# b_stream[k + 1] = mv[i + 1]
# b_stream[k + 2] = mv[i]
# k+=3
for i in range(0, len(mv), 3): #4
if i % (width*3) == 0:
b_stream.append(0)
k += 1
b_stream.append(mv[i + 2])
b_stream.append(mv[i + 1])
b_stream.append(mv[i])
# b_stream.extend([mv[i + 2],mv[i + 1],mv[i]])
k+=3
# b_stream.append(mv[i+2])
# b_stream.append(mv[i+1])
# b_stream.append(mv[i+0])
# b_stream.append(mv[i+3])
# k+=4
# print(b_stream)
print(time.time() - s)
def crc32(data): # 字节流
crc = zlib.crc32(data)
return crc
def crc32_b(data):
crc = zlib.crc32(data).to_bytes(4, byteorder='big')
return crc
# png图片标识符
png_signature = b"\x89PNG\r\n\x1a\n"
# IHDR块
ihdr = struct.pack("!IIBBBBB", width, height, 8, 2, 0, 0, 0) # 8 6 0 0 0
# IHDR的CRC验证
mid = crc32_b(b"IHDR" + ihdr)
# 压缩图片数据
bd = zlib.compress(bytes(b_stream))
# IDAT的CRC验证
crc_bytes = crc32_b(bd)
idat_chunk = b"IDAT" + bd + crc_bytes
# IEND块
iend = b"\x00\x00\x00\x00IEND"
# IEND的CRC验证
crc_end = crc32_b(b"IEND")
iend += crc_end
# 写入图片操作,使用BytesIO来构建PNG
png_io = io.BytesIO()
png_io.write(png_signature + b"\x00\x00\x00\rIHDR" + ihdr + mid)
idat_header = struct.pack("!I", len(bd))
png_io.write(idat_header + idat_chunk)
png_io.write(iend)
# 一次性写入文件
with open("photo.png", "wb") as f:
f.write(png_io.getvalue())
# 恢复设备上下文
gdi32.SelectObject(hdc_dest, old_bmp)
# 删除内存设备上下文
gdi32.DeleteDC(hdc_dest)
# 释放桌面窗口的设备上下文
user32.ReleaseDC(hwnd, hdc_src)
# bmp已经被处理,现在删除它
gdi32.DeleteObject(bmp)
# 进行截图
for i in range(10):
x = capture_screen(0, 0, screenWidth, screenHeight)
if x != 0:
break
print(time.time() - s)