赞
踩
经过两天的研究,
思路:投屏到电脑,然后windows窗体截图。
具体思路是:可以使用投屏软件,把安卓屏幕投到电脑上,然后根据句柄,截取windows窗口截图
于是,我根据思路,,研究出来了使用python【当然如果精通其它语言,不会python,可以根据上面的思路自行写代码】,写出了可运行的python代码。
下面是具体方式
一、安装ADB,SCRCPY。
ADB的安装就不说了,还需要安卓手机开发者设置:里面打开USB调试开关。诸君自行搜索
SCRCPY是github上star最多的开源投屏
scrcpy使用:
解压缩
设置windows环境变量->系统变量->path->添加一个指向解压缩后的文件夹路径
打开cmd
命令提示符cmd中输入 【scrcpy -s 安卓手机序列号】
然后scrcpy就会弹出安卓投屏了
二、python代码
思路:使用os调用系统cmd打开安卓投屏,找到安卓投屏窗口句柄,根据句柄进行窗口截图
使用库:os库,win32gui库,PILLOW库
os库是python默认库,不需要安装
win32gui库,不能直接pip install win32gui【它不支持python3.9,最多仅支持3.6】
正确install代码:
pip install -i https://pypi.doubanio.com/simple/ pypiwin32
pillow库:网上很多教程,自行搜索
三、具体代码如下:
- import time,os,datetime
- from PIL import Image
- import win32gui, win32ui, win32api, win32con
-
- hwnd_title = dict()#获取windows窗口句柄+标题
-
- def cut_pic_by_filename_XY(filename, x1, y1, x2, y2): # 根据图片路径,打开图片,并裁剪图片【从x1,y1到x2,y2】,然后保存裁剪出来的图片到硬盘
- img = Image.open(filename) ## 打开filename文件,并赋值给img
- imgSize = img.size # 大小/尺寸
- w = img.width # 图片的宽
- h = img.height # 图片的高
- f = img.format # 图像格式
- region = img.crop((x1, y1, x2, y2)) # 裁剪图片【从x1,y1到x2,y2】
- current_date = datetime.datetime.now().strftime('%Y%m%d')#提取日期
- save_path_dir = "./image/save_image/" + current_date
- if not os.path.exists(save_path_dir):#文件夹不存在,则创建文件夹
- os.makedirs(save_path_dir)
- str_time = str(int(time.time()))#提取时间戳
- pic_filename = filename.split("/")[-1]#提取路径中的文件名
- region.save(save_path_dir + "/" + str_time + pic_filename) ## 将裁剪下来的图片保存到 时间戳+文件名.png
- return save_path_dir + "/" + str_time + pic_filename#返回文件路径
-
- def _get_all_hwnd(hwnd, mouse):
- if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
- hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)})
-
- def window_capture(filename, hwnd):#窗口截屏
- #hwnd = 0 # 窗口的编号,0号表示当前活跃窗口
- # 根据窗口句柄获取窗口的设备上下文DC(Divice Context)
- hwndDC = win32gui.GetWindowDC(hwnd)
- # 根据窗口的DC获取mfcDC
- mfcDC = win32ui.CreateDCFromHandle(hwndDC)
- # mfcDC创建可兼容的DC
- saveDC = mfcDC.CreateCompatibleDC()
- # 创建bigmap准备保存图片
- saveBitMap = win32ui.CreateBitmap()
- # 获取监控器信息
- MoniterDev = win32api.EnumDisplayMonitors(None, None)
- w = MoniterDev[0][2][2]
- h = MoniterDev[0][2][3]
- w2 = 600#设置截图的X轴宽度【可根据截图保存的文件filename查看,然后实际调整】
- h2 = 1080#设置截图的Y轴高度【可根据截图保存的文件filename查看,然后实际调整】
- # print w,h #图片大小
- # 为bitmap开辟空间
- saveBitMap.CreateCompatibleBitmap(mfcDC, w2, h2)
- # 高度saveDC,将截图保存到saveBitmap中
- saveDC.SelectObject(saveBitMap)
- # 截取从左上角(0,0)长宽为(w,h)的图片
- saveDC.BitBlt((0, 0), (w2, h2), mfcDC, (0, 0), win32con.SRCCOPY)
- saveBitMap.SaveBitmapFile(saveDC, filename)
- #上面的截图尺寸不行,我就自己写了一个精确截图的def,其中x1,y1,x2,y2,诸君自行对比窗口截图
- backpng = cut_pic_by_filename_XY(filename, 10, 45, 590, 1070)
- return backpng
- #可以运行以下注释的代码,获得手机的序列号,诸君可自行提取自己的手机序列号
- #cmdstr = "adb devices"
- #backstr = os.popen(cmdstr).read()
- #print(backstr)
- device_name = "b038bc0b"
- device_n = ' -s ' + device_name
- #scrcpy --crop设定屏幕=1080*1920并且偏移坐标为 (0,0)
- #这里的--crop命令就是老版本的-c命令,新版本升级了,-c命令是错误的了。
- #然而:网上面的所有有关scrcpy命令的教程文档,全部还是-c命令,真鸡儿扯淡,害我查半天
- #-m 1024 限制画面分辨率=1024
- #-b 4M修改视频码率=4M
- # --window-x 100 --window-y 200 --window-width 405 --window-height 720设定窗体起始坐标,设置窗体宽和高
- win_title = "MY_Test1"
- #注意这里是windows窗体标题,最好每次打开的windows窗体标题不同,否则多个窗体标题一样的话
- #会出现错误,找不到句柄
- cmdstr = "scrcpy" + device_n + " --crop=1080:1920:0:0 --window-title "
- cmdstr = cmdstr + win_title
- cmdstr = cmdstr + " -m 1024 -b 4M"
- os.popen(cmdstr)#打开scrcpy
- time.sleep(3)#等待3秒,等待窗体彻底弹出
- win32gui.EnumWindows(_get_all_hwnd, 0)#获取所有windows窗口句柄
- hwnd = 0
- for wnd in hwnd_title.items():#循环获取所有的windows句柄
- print(wnd)#句柄值示例:(325674,"MI 5"):前面是windows句柄ID,后面是windows窗口标题
- get_win_title = str(wnd[1])
- if win_title == get_win_title:#根据windows窗口标题判断,是不是需要截图的窗口。
- hwnd = wnd[0]
- break
- print("windows句柄ID:", hwnd)
- cut_image_file = './image/scrcpy' + str(device_name) + '.png'
- get_png = window_capture(cut_image_file, hwnd)#对windows窗体进行截图
- print(get_png)
- #关闭windows窗体
- #win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
如上,可以截屏。
录屏的话:scrcpy有个录屏启动命令,直接使用该命令启动scrcpy,然后操作scrcpy弹出的投屏窗口,scrcpy会保存操作视频
scrcpy -s 手机序列号 --record file.mp4
代码没仔细研究,诸君可自行研究。思路:os用上述代码,操作cmd打开scrcpy,然后python控制鼠标scrcpy弹出的窗口,在该窗口上点击,滑动等等具体的操作,最后看file.mp4
看到有兄弟问了,黑屏的时候还是黑的,这是因为该APP使用了FLAG_SECURE,两个都禁了【截屏录屏】和【投屏】.
Android代码是这样:
在Activity的onCreate事件中,setFlags【禁止截屏录屏】注册广播接收器,监听投屏事件【禁止投屏】
- import android.app.Activity;
- import android.content.Context;
- import android.content.IntentFilter;
- import android.media.projection.MediaProjectionManager;
- import android.os.Bundle;
- import android.view.WindowManager;
-
- public class MainActivity extends Activity {
- private ScreenCaptureBroadcastReceiver receiver;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- // 禁止截屏
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
-
- // 注册广播接收器,监听投屏事件
- receiver = new ScreenCaptureBroadcastReceiver();
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_SCREEN_ON);
- intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
- registerReceiver(receiver, intentFilter);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- // 注销广播接收器
- unregisterReceiver(receiver);
- }
-
- // 广播接收器类,用于监听投屏事件
- private class ScreenCaptureBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- // 检测到投屏事件发生
- if (Intent.ACTION_SCREEN_ON.equals(intent.getAction()) ||
- Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
- // 禁用投屏功能
- MediaProjectionManager mediaProjectionManager = (MediaProjectionManager)
- getSystemService(Context.MEDIA_PROJECTION_SERVICE);
- if (mediaProjectionManager != null) {
- mediaProjectionManager.stopScreenCapture();
- }
- }
- }
- }
- }
如果仅仅禁止截屏录屏的话,可以用我上文的:投屏到电脑的办法,可以解决
如果是用MediaProjectionManager监听投屏的话:
MediaProjectionManager是Android提供的一个类,用于管理屏幕捕捉(Screen Capture)功能。
请注意,使用MediaProjectionManager需要申请android.permission.CAPTURE_VIDEO_OUTPUT权限,并且只能在Android 5.0(API级别21)及以上的设备上使用。此外,屏幕捕捉功能通常在需要进行屏幕录制、屏幕分享等场景下使用,并非所有应用都需要使用或禁用该功能。
你可以尝试把该APP的CAPTURE_VIDEO_OUTPUT权限关闭【中文权限名:捕获视频输出】,有很多手机找不到该权限,
不过关闭权限也未必管用,
有哪位同学知道的,可以给个文章地址,不过这涉及系统权限的修改,我估计要root手机,然后装xposed框架,然而,我对于xposed框架不熟,有会的同学,不妨留言。
还有物理办法:A手机操作,B手机在旁打开相机录制。
诸君自行研究吧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。