试验SurfaceFlinger 中Source Crop

news2024/12/28 20:04:06

在 SurfaceFlinger 中,Source Crop 是用于指定源图像的裁剪区域的一个概念。Source Crop 可以理解为是一个矩形区域,它定义了源图像中要被渲染到目标区域的部分。在 Android 中,Source Crop 通常用于实现屏幕分辨率适应和缩放等功能。

在 SurfaceFlinger 中,每个图层都有一个 Source Crop 的属性,用于指定该图层在源图像中的裁剪区域。当 SurfaceFlinger 按照图层顺序将图层合成到最终的目标缓冲区时,它会根据每个图层的 Source Crop 和目标区域的尺寸来计算出该图层在目标区域中的显示位置和大小。这样,就可以实现对源图像的裁剪和缩放等操作。

在 Android 应用程序中,我们可以使用 SurfaceView 或者 TextureView 等组件来创建一个图层,并在它上面绘制自己的图形。在创建图层时,我们可以通过设置组件的 SurfaceHolder 或者 SurfaceTexture 等对象的 Source Crop 属性来指定图层的裁剪区域,从而实现对图层的缩放和裁剪等操作。

以下是一个示例代码,展示了如何使用 SurfaceView 和 SurfaceHolder 来创建一个图层,并设置其 Source Crop 属性:

javaCopy

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder holder;
    public MySurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 获取 SurfaceHolder 对象
        holder = getHolder();

        // 添加回调函数
        holder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // 获取 Canvas 对象
        Canvas canvas = holder.lockCanvas();

        // 设置 Source Crop 属性
        Rect sourceCrop = new Rect(0, 0, 400, 400);
        holder.setFixedSize(sourceCrop.width(), sourceCrop.height());

        // 绘制图形
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        canvas.drawRect(sourceCrop, paint);

        // 解锁画布,并提交绘制内容
        holder.unlockCanvasAndPost(canvas);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // Do nothing
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // Do nothing
    }
}

在上面的代码中,我们创建了一个自定义的 SurfaceView 组件,并实现了 SurfaceHolder.Callback 接口的三个回调函数。在 surfaceCreated() 回调函数中,我们获取了 SurfaceHolder 对象并通过 lockCanvas() 方法获取了一个 Canvas 对象。然后,我们设置了 Source Crop 属性,并使用 Canvas 绘制了一个红色矩形。最后,我们调用 unlockCanvasAndPost() 方法解锁画布,并提交绘制内容。

需要注意的是,在设置 Source Crop 属性时,我们使用了 SurfaceHolder 的 setFixedSize() 方法来指定目标区域的尺寸。这是因为,Source Crop 只能裁剪图像,不能改变图像的大小。因此,如果要实现缩放等操作,必须通过设置目标区域的尺寸来实现。

通过setFixedSize可以设置绘制的大小,这里我们进行测试,在一个activity中准备3个按钮,点击按钮来绘制不同大小的画布,看看效果。

首先看看屏幕的大小

adb shell wm size

Physical size: 1600x2560

准备设置3个大小的画布来进行试验

1 480X800

2 1600x2560

3 2600x3560

package com.example.testsize;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(view -> {
            Intent intent = new Intent(MainActivity.this, newActivity.class);
            intent.putExtra("id", 1);
            startActivity(intent);
        });

        findViewById(R.id.button2).setOnClickListener(view -> {
            Intent intent = new Intent(MainActivity.this, newActivity.class);
            intent.putExtra("id", 2);
            startActivity(intent);
        });

        findViewById(R.id.button3).setOnClickListener(view -> {
            Intent intent = new Intent(MainActivity.this, newActivity.class);
            intent.putExtra("id", 3);
            startActivity(intent);
        });
    }
}

newActivity代码

package com.example.testsize;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class newActivity extends AppCompatActivity {

    private SurfaceView surfaceView;
    private int gameWidth = 480; // 游戏画面宽度
    private int gameHeight = 800; // 游戏画面高度
    private int gameFps = 3; // 游戏画面帧率 60
    private int squareSize = 100; // 小方块尺寸
    private int squareX = 20; // 小方块横向位置
    private int squareX2 = 1560; // 小方块横向位置2

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new);

        //get data
        Intent intent = getIntent();
        int id = intent.getIntExtra("id", 0);
        if (id == 2) {
            gameWidth = 1600;
            gameHeight = 2560;
        } else if (id == 3) {
            gameWidth = 2600;
            gameHeight = 3560;
        }

        // 获取 SurfaceView 组件
        surfaceView = findViewById(R.id.surfaceView);

        // 设置游戏画面的尺寸和绘制速度等参数
        surfaceView.getHolder().setFixedSize(gameWidth, gameHeight);
        surfaceView.getHolder().setFormat(PixelFormat.RGBA_8888);
        surfaceView.getHolder().setKeepScreenOn(true);
        surfaceView.getHolder().setFormat(PixelFormat.TRANSPARENT);
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                // 游戏画面创建时的初始化操作
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // 获取 Canvas 组件
                        Canvas canvas = surfaceView.getHolder().lockCanvas();

                        // 在 Canvas 上绘制游戏画面
                        Paint paint = new Paint();
                        paint.setColor(Color.RED);
                        canvas.drawRect(squareX, gameHeight / 2 - squareSize / 2, squareX + squareSize, gameHeight / 2 + squareSize / 2, paint);

                        //draw rect 2
                        canvas.drawRect(squareX2, gameHeight / 2 - squareSize / 2, squareX2 + squareSize, gameHeight / 2 + squareSize / 2, paint);

                        // 释放 Canvas 组件
                        surfaceView.getHolder().unlockCanvasAndPost(canvas);

                        // 循环更新游戏画面
                        while (true) {
                            /*
                            // 获取 Canvas 组件
                            Canvas canvas1 = surfaceView.getHolder().lockCanvas();

                            // 在 Canvas 上绘制游戏画面
                            Paint paint1 = new Paint();
                            paint1.setColor(Color.RED);
                            canvas1.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                            canvas1.drawRect(squareX, gameHeight / 2 - squareSize / 2, squareX + squareSize, gameHeight / 2 + squareSize / 2, paint1);

                            // 更新小方块位置
                            squareX += 5;
                            if (squareX > gameWidth) {
                                squareX = 0;
                            }


                            // 释放 Canvas 组件
                            surfaceView.getHolder().unlockCanvasAndPost(canvas1);

                             */

                            // 控制游戏画面的帧率
                            try {
                                Thread.sleep(1000 * 100 / gameFps);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                // 游戏画面尺寸发生变化时的操作
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                // 游戏画面销毁时的操作
            }
        });
    }
}

布局activity_new.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".newActivity">

    <SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

试验效果图

  1. 截取了480X800,由于比屏幕小,在屏幕上进行了放大

dumpsys SurfaceFlinger

Display 4630947232161729154 (active) HWC layers:

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Layer name

Z | Window Type | Layer Class | Comp Type | Transform | Disp Frame (LTRB) | Source Crop (LTRB) | Frame Rate (Explicit) (Seamlessness) [Focused] [FrameBooster]

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

SurfaceView[com.example.testsize/com[...]testsize.newActivity]@0(BLAST)#21860

rel 0 | 0 | 0 | DEVICE | 0 | 0 187 1600 2458 | 0.0 0.0 480.0 800.0 | [*] [ ]

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

com.example.testsize/com.example.testsize.newActivity$_15842#21855

rel 0 | 1 | 0 | DEVICE | 0 | 0 0 1600 2560 | 0.0 0.0 1600.0 2560.0 | [*] [ ]

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

MSHandler:com.example.testsize/com.e[...]ize.newActivity@709a0f3$_15842#21868

rel 0 | 2 | 0 | DEVICE | 0 | 630 0 970 163 | 0.0 9.0 340.0 172.0 | [ ] [ ]

2. 1600x2560,和屏幕大小一致,

Display 4630947232161729154 (active) HWC layers:

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Layer name

Z | Window Type | Layer Class | Comp Type | Transform | Disp Frame (LTRB) | Source Crop (LTRB) | Frame Rate (Explicit) (Seamlessness) [Focused] [FrameBooster]

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

SurfaceView[com.example.testsize/com[...]testsize.newActivity]@0(BLAST)#21919

rel 0 | 0 | 0 | DEVICE | 0 | 0 187 1600 2458 | 0.0 0.0 1600.0 2560.0 | [*] [ ]

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

com.example.testsize/com.example.testsize.newActivity$_15842#21914

rel 0 | 1 | 0 | DEVICE | 0 | 0 0 1600 2560 | 0.0 0.0 1600.0 2560.0 | [*] [ ]

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

MSHandler:com.example.testsize/com.e[...]ize.newActivity@8ba4b78$_15842#21927

rel 0 | 2 | 0 | DEVICE | 0 | 630 0 970 163 | 0.0 9.0 340.0 172.0 | [ ] [ ]

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3. 画布是2600x3560,大于屏幕大小,在显示到屏幕的时候进行了缩小处理

Display 4630947232161729154 (active) HWC layers:

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Layer name

Z | Window Type | Layer Class | Comp Type | Transform | Disp Frame (LTRB) | Source Crop (LTRB) | Frame Rate (Explicit) (Seamlessness) [Focused] [FrameBooster]

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

SurfaceView[com.example.testsize/com[...]testsize.newActivity]@0(BLAST)#21959

rel 0 | 0 | 0 | DEVICE | 0 | 0 187 1600 2458 | 0.0 0.0 2600.0 3560.0 | [*] [ ]

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

com.example.testsize/com.example.testsize.newActivity$_15842#21954

rel 0 | 1 | 0 | DEVICE | 0 | 0 0 1600 2560 | 0.0 0.0 1600.0 2560.0 | [*] [ ]

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

实际效果 3截图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/609105.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java基础篇】逻辑控制练习题与猜数字游戏

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a;Java.SE&#xff0c;本专栏主要讲解运算符&#xff0c;程序逻辑控制&#xff0c;方法的使用&…

2023_Python全栈工程师入门教程目录

2023_Python全栈工程师入门教程 该路线来自慕课课程,侵权则删,支持正版课程,课程地址为:https://class.imooc.com/sale/python2021 学习路线以三个项目推动,一步步夯实技术水平&#xff0c;打好Python开发基石 目录: 1.0 Python基础入门 2.0 Python语法进阶 3.0 Python数据…

windows系统典型漏洞分析

内存结构 缓冲区溢出漏洞 缓冲区溢出漏洞就是在向缓冲区写入数据时&#xff0c;由于没有做边界检查&#xff0c;导致写入缓冲区的数据超过预先分配的边界&#xff0c;从而使溢出数据覆盖在合法数据上而引起系统异常的一种现象。 ESP、EPB ESP&#xff1a;扩展栈指针&#xff08…

React.memo()、userMemo 、 userCallbank的区别及使用

本文是对以下课程的笔记输出&#xff0c;总结的比较简洁&#xff0c;若大家有不理解的地方&#xff0c;可以通过观看课程进行详细学习&#xff1b; React81_React.memo_哔哩哔哩_bilibili React76_useEffect简介_哔哩哔哩_bilibili React136_useMemo_哔哩哔哩_bilibili Rea…

直播录音时准备一副监听耳机,实现所听即所得,丁一号G800S上手

有些朋友在录视频还有开在线会议的时候&#xff0c;都会遇到一个奇怪的问题&#xff0c;就是自己用麦克风收音的时候&#xff0c;自己的耳机和别人的耳机听到的效果不一样&#xff0c;像是音色、清晰度不好&#xff0c;或者是缺少伴奏以及背景音嘈杂等&#xff0c;这时候我们就…

2023贵工程团体程序设计赛

A这是一道数学题&#xff1f; 道路有两边。 #include<bits/stdc.h> using namespace std; int main(){int n,m;cin>>n>>m;cout<<(n/m1)*2;return 0; } BCPA的团体赛 直接输出 。 #include <bits/stdc.h> using i64 long long; #define IOS…

Docker基本管理与网络以及数据管理

目录 一、Docker简介1、Docker简述2、什么是容器3、容器的优点4、Docker的logo及设计宗旨5、Docker与虚拟机的区别6、Docker的2个重要技术7、Docker三大核心概念 二、Docker的安装及管理1、安装Docker2、配置Docker加速器3、Docker镜像相关基础命令①搜索镜像②拉取镜像③查看镜…

Linux 配置Tomcat环境(二)

Linux 配置Tomcat环境 二、配置Tomcat1、创建一个Tomcat文件夹用于存放Tomcat压缩包2、把Tomcat压缩包传入服务器3、解压并启动Tomcat4、CentOS开放8080端口 二、配置Tomcat 1、创建一个Tomcat文件夹用于存放Tomcat压缩包 输入指令 cd /usr/local 进入到 usr/local 输入指令 …

[LsSDK][tool] ls_syscfg_gui2.0

文章目录 一、简介1.工具的目的2. 更新点下个更新 三、配置文件 一、简介 1.工具的目的 ① 可视化选择IO口功能。 ② 自由配置IO支持的功能。 ③ 适用各类MCU&#xff0c;方便移植和开发。 ④ 功能配置和裁剪&#xff08;选项-syscfg-待完成–需要适配keil语法有些麻烦&#…

Node.js: express + MySQL + Vue实现图片上传

前段时间用Node.js: express MySQL Vue element组件做了一个小项目&#xff0c;记录一下图片上传的实现。 将图片存入数据库有两种方法&#xff1a; 1&#xff0c;将图片以二进制流的方式存入数据库&#xff08;数据库搬家容易&#xff0c;比较安全&#xff0c;但数据库空间…

微服务实战项目-学成在线-媒资管理模块(有项目实战实现)

学成在线-媒资管理模块 1 模块需求分析 1.1 模块介绍 媒资管理系统是每个在线教育平台所必须具备的&#xff0c;查阅百度百科对它的定义如下&#xff1a; 媒体资源管理(Media Asset Management&#xff0c;MAM)系统是建立在多媒体、网络、数据库和数字存储等先进技术基础上…

SpringCloud服务接口调用

SpringCloud服务接口调用 OpenFeign 是什么? 能干啥? 两者区别 OpenFeign使用 接口注解 微服务调用接口FeignClient Feign在消费端使用 新建cloud-consumer-feign-order80 导入eureka和openfeign依赖: <dependency><groupId>org.springframework.cloud&l…

Nginx 中的Rewrite讲解

这里写目录标题 常用的Nginx正则表达式locationelocation 分类location 常用的匹配规则location 优先级 总结RewriteRewrite全局变量是什么?rewrite 执行顺序如下&#xff1a;语法格式&#xff1a;rewrite \<regex> \<replacement> [flag];flag标记说明基于域名的…

STL入门 + 刷题(上)

&#x1f442; 【纯音&吉他】洋溢着青春气息的轻快旋律 - 歌单 - 网易云音乐 听着吉他纯音&#xff0c;看书做题&#xff0c;真是一种享受~ 补充&#xff1a;点击链接后&#xff0c;左上角有个提交按钮&#xff0c;在《算法训练营》的网站可以直接提交&#xff0c;而不需要…

BEVFormer组件分析

BEVFormerEncoder中的get_reference_points staticmethoddef get_reference_points(H, W, Z8, num_points_in_pillar4, dim3d, bs1, devicecuda, dtypetorch.float):"""Get the reference points used in SCA and TSA.Args:H, W: spatial shape of bev.Z: hight…

让你的代码动起来:Python进度条神器tqdm详解及应用实例

各位Python高手&#xff0c;今天我要给大家介绍一个好用的库&#xff0c;它就是&#xff1a;tqdm tqdm在阿拉伯语中的意思是 "进展"&#xff0c;所以这个库也被称为 "快速进展条"。不得不说&#xff0c;这个名字真的很有创意&#xff01; 让我们想象一下&a…

蒙特卡洛积分——采样方法

蒙特卡洛积分 目的&#xff1a; 通过计算机进行采样近似求解复杂的积分理论基础&#xff1a; 大数定律&#xff0c;当 n n n足够大时&#xff0c; X X X的均值将收敛于它的期望&#xff08;不严谨表述&#xff09;一般形式&#xff1a; θ ∫ a b f ( x ) d x ∫ a b f ( x…

瑞云科技CTO赵志杰出席广州广告数字创意峰会并发表演讲

3月23日下午&#xff0c;广州广告数字创意峰会暨穗广协企业家大讲堂年度巡礼活动在广州图书馆圆满举行。本次峰会由广州市人民政府统筹&#xff0c;中共广州市委宣传部、广州市文化广电旅游局、中共广州市天河区委、广州市天河区人民政府主办。作为第六届“文创产业大会天河峰会…

go调试工具-delve

go调试工具-delve 简介 go debug工具&#xff0c;专门为go开发的调试工具&#xff0c;并且采用go语言开发&#xff0c;支持多平台。 官网&#xff1a;https://github.com/go-delve/delve 官网有详细的手册&#xff0c;学习起来很方便 快速开始 安装 我本地的go版本 官方…

python的基本知识与面试问题的汇总1

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下python的基本知识与面试问题的汇总&#xff0c;看完之后会对python巩固有很大的帮助哦。 Python中的多线程&#xff1a; 多线程是指在一个程序中同时运行多个线程以提高程序的执行效率。Python中的threading模块…