试验SurfaceFlinger 中Source Crop

news/2024/11/23 2:46:56/

在 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);}@Overridepublic 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);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {// Do nothing}@Overridepublic 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")@Overrideprotected 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; // 游戏画面帧率 60private int squareSize = 100; // 小方块尺寸private int squareX = 20; // 小方块横向位置private int squareX2 = 1560; // 小方块横向位置2@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_new);//get dataIntent 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() {@Overridepublic void surfaceCreated(SurfaceHolder holder) {// 游戏画面创建时的初始化操作new Thread(new Runnable() {@Overridepublic 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 2canvas.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();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {// 游戏画面尺寸发生变化时的操作}@Overridepublic 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"><SurfaceViewandroid: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.ppmy.cn/news/211626.html

相关文章

【SpringCloud学习笔记】zuul网关

【SpringCloud学习笔记】 为什么需要网关zuul网关搭建zuul网关服务网关过滤器 为什么需要网关 微服务项目一般有多个服务&#xff0c;每个服务的地址都不同&#xff0c;客户端如果直接访问服务&#xff0c;无疑是增加客户端开发难度&#xff0c;项目小还好&#xff0c;如果项目…

5轴雕刻机同款运动系统。 USB运动控制 (五轴雕刻机系统)全部开源 不保留任何关键技术,PCB可直接生产

pocket nc 5轴雕刻机同款运动系统。 USB运动控制 (五轴雕刻机系统)全部开源 不保留任何关键技术&#xff0c;PCB可直接生产&#xff0c;C6.0源码&#xff0c;&#xff0c;本产品为可复制资料&#xff0c;支持五轴联动&#xff0c;支持RTCP算法&#xff0c;全部开源。 送后置处…

使用雕刻机自制钢网

当你因为某些原因需要自制钢网时&#xff0c;可以参考一下本文的教程。以下过程是本人摸索出来的&#xff0c;可能有其他更好的方法&#xff0c;仅供参考。 需要工具&#xff1a;雕刻机 需要软件&#xff1a;Altium Designer、fusion 360 生成Gerber文件 首先新建一个文件夹&a…

IDEA常用快捷键大全(详解)

目录 前言 一. Ctrl相关 二. Alt相关 三. Shift相关 四. Ctrl Alt相关 五. Ctrl Shift相关 六. Alt Shift相关 七. 其他 汇总 前言 IDEA 中提供了很多快捷键&#xff0c;点击File --> Settings --> keymap便可进入看到 IDEA 提供的快捷键。我们也可以搜索和自…

VEAZEN费森VZ200 VS雅马哈F310,你会怎么选择?初学者吉他推荐选购

VEAZEN费森VZ200 VS雅马哈F310&#xff0c;你会怎么选择&#xff1f; 很多新手在选择第一把吉他的时候&#xff0c;都会在相同价位里进行比较和选择&#xff0c;相同价位的吉他配置都差不多&#xff0c;新手想要选择一个性价比高的还是比较困难的&#xff0c;因此&#xff0c;为…

艾肯声卡调试机架安装教程与下载_2019最新推荐

哈喽大家好&#xff0c;我是你们的老朋友声卡调试专业网站长小伙音频技术&#xff0c;2019年度艾肯认证授权调音师&#xff0c;尤其擅长各款网络主播直播专用独立声卡的效果精调&#xff01; 艾肯声卡分老款与新款VST系列&#xff0c;常用ICON声卡micu VST&#xff0c;4nano VS…

艾肯声卡调试方法【必看】

艾肯声卡是一种用来网络主播&#xff0c;娱乐&#xff0c;K歌的声卡&#xff0c;也可以用于现场主持&#xff0c;K歌&#xff0c;表演&#xff0c;演讲&#xff0c;同时还可以用于后期录音&#xff0c;混音&#xff0c;编曲等&#xff0c;功能较多。它主要连接在我们电脑的usb接…

半入耳蓝牙耳机哪款好?音质好高性价比的半入耳式蓝牙耳机

目前主流的入耳式和半入耳式&#xff0c;入耳式在音质&#xff0c;降噪等方面确实是优势所在&#xff0c;但长时间佩戴下耳朵会有不适&#xff0c;相信也是大多数用户比较纠结的点&#xff0c;而半入耳式佩戴起来舒适感会好很多&#xff0c;适合长期佩戴&#xff0c;所以笔者专…