Android 实现全屏截图、剪裁图片、分享图片至其他应用进程功能(踩坑记录)

本文记录了在Android项目中实现全屏截图、剪裁以去除状态栏和标题栏,并实现图片分享功能的过程。遇到的问题包括:全屏截图方法在API28以上被弃用以及MaterialCardView圆角截图显示失效。通过使用PixelCopy解决截图问题,并成功剪裁图片,最终完成分享功能。
摘要由CSDN通过智能技术生成

Android 实现全屏截图、剪裁、分享功能

项目中需要用到 截图分享 的功能,特此写下查询资料过程中的踩坑记录。
android 26以上,google 官方文档支持 PixelCopy 实现截图效果
获取虚拟导航栏的高度并剪裁图片

1、全屏截图

1.1 踩坑记录

第一个坑:方法已被弃用

(先前实现的全屏截图方法,已经在api28及以上弃用)

在这里插入图片描述

 // View是全屏截图  **已弃用**
        View getView = this.getWindow().getDecorView();
        getView.setDrawingCacheEnabled(true);
        getView.buildDrawingCache();
        Bitmap b1 = getView.getDrawingCache();

第二个坑:能实现全屏截图,但是 MaterialCardView 圆角显示失效
在这里插入图片描述

//获取全屏截图(包括状态栏、标题栏和底部)
        val screenView = window.decorView
        val bitmap = screenView.drawToBitmap()

1.2 正确截图方式

经过查询资料,终于找到了能正确显示 MaterialCardView 圆角的截图方式
在这里插入图片描述

val EVENT_SCREENSHOT = 22 //截图事件

    private var mediaProjectionManager: MediaProjectionManager? = null
    private var mediaProjection: MediaProjection? = null
    private var image: Image? = null

    private fun takeScreenShot() {
   
        mediaProjectionManager = application.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        startActivityForResult(mediaProjectionManager!!.createScreenCaptureIntent(), EVENT_SCREENSHOT)
    }

    @SuppressLint("WrongConstant")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
   

        super.onActivityResult(requestCode, resultCode, data)

        if(requestCode == EVENT_SCREENSHOT_LOCK ||requestCode == EVENT_SCREENSHOT_SHARE){
   

            val displayMetrics = resources.displayMetrics
            val width = displayMetrics.widthPixels
            val height = displayMetrics.heightPixels

            val mImageReader: ImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2)
            mediaProjection = mediaProjectionManager!!.getMediaProjection(resultCode, data!!)
            val virtualDisplay = mediaProjection!!.createVirtualDisplay("screen-mirror", width, height,
                    displayMetrics.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.surface, null, null)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
可以使用Python调用C语言的方式实现全屏截图,并将截图传入Tkinter中进行显示。下面是一个简单的实现过程: 1. 编写C语言代码实现全屏截图,这里可以使用Windows API函数实现,例如GetDesktopWindow()、GetWindowRect()和BitBlt()等函数。 ```c #include <Windows.h> HBITMAP CaptureScreen() { HDC hdcScreen = GetDC(NULL); HDC hdcMem = CreateCompatibleDC(hdcScreen); int width = GetDeviceCaps(hdcScreen, HORZRES); int height = GetDeviceCaps(hdcScreen, VERTRES); HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, width, height); HGDIOBJ hOld = SelectObject(hdcMem, hBitmap); BitBlt(hdcMem, 0, 0, width, height, hdcScreen, 0, 0, SRCCOPY); SelectObject(hdcMem, hOld); DeleteDC(hdcMem); ReleaseDC(NULL, hdcScreen); return hBitmap; } ``` 2. 将C语言代码编译为动态链接库(DLL)文件,使用Python的ctypes模块调用DLL文件中的函数。 ```c #include <Windows.h> __declspec(dllexport) HBITMAP CaptureScreen() { HDC hdcScreen = GetDC(NULL); HDC hdcMem = CreateCompatibleDC(hdcScreen); int width = GetDeviceCaps(hdcScreen, HORZRES); int height = GetDeviceCaps(hdcScreen, VERTRES); HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, width, height); HGDIOBJ hOld = SelectObject(hdcMem, hBitmap); BitBlt(hdcMem, 0, 0, width, height, hdcScreen, 0, 0, SRCCOPY); SelectObject(hdcMem, hOld); DeleteDC(hdcMem); ReleaseDC(NULL, hdcScreen); return hBitmap; } ``` ```python import ctypes from PIL import Image, ImageTk import tkinter as tk # 加载DLL文件 dll = ctypes.windll.LoadLibrary("screenshot.dll") # 调用C语言函数获取全屏截图 hBitmap = dll.CaptureScreen() # 将HBITMAP对象转换为PIL Image对象 pil_image = Image.fromhandle(hBitmap) # 将PIL Image对象转换为Tkinter PhotoImage对象 tk_image = ImageTk.PhotoImage(image=pil_image) # 在窗口中显示截图 root = tk.Tk() label = tk.Label(root, image=tk_image) label.pack() root.mainloop() ``` 注意,在使用完HBITMAP对象后需要使用DeleteObject()函数进行释放,否则会出现内存泄漏的问题。 ```c __declspec(dllexport) void DeleteBitmap(HBITMAP hBitmap) { DeleteObject(hBitmap); } ``` ```python # 使用完HBITMAP对象后释放内存 dll.DeleteBitmap(hBitmap) ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值