视图变化 - 等比例变换防止视图拉伸

news2024/12/27 18:34:11

文章目录

      • 使用场景
      • 等比变换
        • 等高填充
        • 等宽填充
        • 代码进行比目标宽高计算
        • 超出部分处理
          • 设置负的 margin
          • clip 裁剪
      • End
      • 参考:

使用场景

在日常开发中,经常会遇到的一个需求是将图片/视频从界面的一个位置,变换到另一个位置。在处理这类问题的时候经常会遇到的一个问题就是比例变化,如果两个位置的宽高比例不一致,如果不做任何处理直接将图像显示到另一个位置图像就会被拉伸。如果使用的是 ImageView 的话,可以设置 scaleType 去选择一个合适的填充方式,但是一些情况下,使用的不是 ImageView 。

以 Android 开发中的相机预览图处理为例,我们通过下面的代码去获取相机的预览图,在手机上,我们获取分辨率,都会有很多分辨率可选:
这里我截取我手机上断点看到的分辨率的可选的列表:

可选择的分辨率很多,一共有 47 个。以 1280*720 ,和 1280*960 两个格式预览图为例,最后换算得到的分辨率的比例分别是 16:9 和 4:3 这两个比例。

因为相机预览图获取到的是的时候横着的,需要这里的比例可以理解为预览图的比例可以理解为 height/width。使用预览图上屏的时需要旋转 90 度。

下面以相机预览图上屏为例进行问题解决。

等比变换

而 Android 手机机型众多,屏幕纵横比也会有很多值,例如有 16 : 9,4 : 3,13 : 6 等多种比例。

等高填充

以一个 16 : 9 纵横比的手机为例,当我们获取到的预览图的比例是 4 : 3 的话,如何把这张 4 : 3 的图片贴到屏幕上避免图片被拉伸呢。

4 : 3 的比例指的宽高比是 3 : 4

在这里插入图片描述
在保持图片比例的情况下,

  • 等高填充:宽度会有一部分超出。
  • 等宽填充:屏幕高度部分会有部分剩余。
等宽填充

那反过来,我们将一个 16 : 9 的预览图放到 4 : 3 的屏幕上,按照不同的变换方式,我们可以得到下面两种变换结果。
在这里插入图片描述
在保持图片比例的情况下,

  • 等高填充:屏幕宽度会有部分剩余。
  • 等宽填充:高度部分会有一些超出。
代码进行比目标宽高计算

因为变换的时候我们的目标都是铺满目标区域,因此我们在变换的时候,采用上面铺满屏幕的变换方式,因此有下面的变换公式,这段代码在 Android 相机处理官方 Demo 中有存在:

			// 预览图变换后的新的 宽高 
            val newWidth: Int
            val newHeight: Int
            val actualRatio = if (width > height) aspectRatio else 1f / aspectRatio
            // 目标区域的宽高比例  和 实际的图片的比例 相比较
            if (width < height * actualRatio) {
                // 对应上面的 16:9 的手机,填充 4:3 的图片
                newHeight = height
                newWidth = (height * actualRatio).roundToInt()
            } else {
            	// 对应上面的 4:3 的手机,填充 16:9 的
                newWidth = width
                newHeight = (width / actualRatio).roundToInt()
            }

上面的代码在对应的地方都加了注释,经过上面的代码我们可以计算得到一个新的宽高。

超出部分处理

在上面计算的变换后的宽高后,超出的部分我们要进行相应的处理,确保画面显示正常

设置负的 margin

以宽超出为例,我们需要设置负的 leftMargin:

如果是高度部分超出的话,就设置对应的负的 topMargin

leftMargin = -(newWidth-originWidth) / 2;

将整体 View 偏移一个 负的距离后,就可以实现整体居中,画面回比较正常。

clip 裁剪

如果没办法将 View 的一部分偏移到界面的不可见部分,那么就将超出的部分裁剪不显示,确保画面的正常。
Android 裁剪方式:参考自己这篇博客中的 clipChildren 默认是 true 进行裁剪
https://blog.csdn.net/liu_12345_liu/article/details/111822877?spm=1001.2014.3001.5502#clipToPadding_1
在这里插入图片描述
鸿蒙上的裁剪方式
在这里插入图片描述
默认为 false ,需要手动设置为 true 。

End

到这里,使用上面的方式,已经可以实现将图片不拉伸显示在界面中,当然如果要避免图片放大后画面模糊,尽量选择一个像素不是那么少的图片进行放大,缩小的话那就不牵扯模糊的问题。

参考:

android platform sample https://github.com/android/platform-samples/tree/main

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

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

相关文章

基于微信小程序的书籍销售预测系统的设计与实现(论文+源码)_kaic

摘 要 随着信息化社会的进步&#xff0c;我们的生活越来越便利。在网上&#xff0c;我们可以轻松地进行各种交易&#xff0c;其中包括图书交易。可以说&#xff0c;图书交易是网络交易的一个重要方面。本系统以面向对象的方式进行开发&#xff0c;使用MySQL作为主要数据存储…

linux centos stream9图形化操作

初学者对图形化操作比较熟悉,对字符界面、命令行比较陌生。本文讨论一下图形化操作的基本技能。希望初学者掌握后尽快使用字符界面,会执行命令,更会编程。 本案例是基于stream9版本,如版本不同,会有差别,注意操作使用。 一、安装图形化界面 Linux操作系统常用的图形用…

Unity URP无光照下Shadow 制作 <二> 合批处理

闲谈 相信大家在日常工作中发现了一个问题 &#xff0c; urp下虽然可以做到3个Pass 去写我们想要的效果&#xff0c;但是&#xff0c;不能合批&#xff08;不能合批&#xff0c;那不是我们CPU要干冒烟~&#xff01;&#xff09; 好家伙&#xff0c;熊猫老师的偏方来了 &#x…

Leetcode JAVA刷刷站(38)外观数列

一、题目概述 二、思路方向 为了解决这个问题&#xff0c;我们可以编写一个Java函数countAndSay&#xff0c;该函数接受一个整数n作为输入&#xff0c;并返回外观数列的第n个元素。这个函数将基于递归公式来构建数列&#xff0c;其中countAndSay(1) "1"&#xff0c;…

vue设置环境变量

1、在根目录地下建立两个文件&#xff0c;.env.development 和 .env.production VUE_APP_BASE_API"" .env.development这个就是开发环境&#xff0c;.env.production这个就是生产环境&#xff0c;也就是这个可以写本地的ip端口 .env.production 这个就是生产环境&…

Verilog刷题笔记51

题目&#xff1a; Now that you have a state machine that will identify three-byte messages in a PS/2 byte stream, add a datapath that will also output the 24-bit (3 byte) message whenever a packet is received (out_bytes[23:16] is the first byte, out_bytes[1…

14、springboot3 vue3开发平台-前端-自定义菜单组件,根据路由动态渲染

文章目录 1. 组件2 . 使用示例 1. 组件 src\components\menuTree\index.vue <template><template v-for"item in menuList"><!-- 分为两种方式渲染&#xff1a;有子菜单和没有子菜单--><!-- 没有子菜单--><el-menu-item :index&qu…

linux cpu问题排查及性能优化

cpu性能 一、cpu啥时候才叫有瓶颈 cpu运行的快还是慢、cpu有没有问题&#xff0c;cpu是不是还需要优化。这些是平常开发和运维中经常遇到的问题。那么我门到底如何去判断机器cpu运行的到底有没有异常呢。 从我排查问题来说&#xff0c;单看系统指标不能完全反应应用运行的状态…

移动魔百盒刷机教程

准备工作 确认型号&#xff1a;首先确认您的魔百盒的具体型号&#xff0c;不同的型号可能需要不同的刷机包。刷机包&#xff1a;下载适合您型号的刷机包。U盘&#xff1a;准备一个容量不超过8GB的U盘&#xff0c;并将其格式化为FAT32格式。刷机工具&#xff1a;根据型号可能需…

深度学习实战:手把手教你构建多任务、多标签模型

多任务多标签模型是现代机器学习中的基础架构&#xff0c;这个任务在概念上很简单 -训练一个模型同时预测多个任务的多个输出。 在本文中,我们将基于流行的 MovieLens 数据集,使用稀疏特征来创建一个多任务多标签模型,并逐步介绍整个过程。所以本文将涵盖数据准备、模型构建、训…

keepalived讲解及练习

目录 1、keepalived介绍 1.1 keepalived简介 2、高可用集群 2.1 集群类型 2.2 系统可用性 2.3 系统故障 2.4 实现高可用 3、VRRP 3.1 VRRP&#xff1a;Virtual Router Redundancy Protocol 3.2 VRRP 相关术语 3.3 VRRP相关技术 4、 keepalived实验 4.1 全局配置 4…

Vue封装axios请求(超详细)

一、简介 Vue封装axios请求是指将axios库集成到Vue项目中&#xff0c;以便更方便地发送HTTP请求。首先&#xff0c;需要安装axios库&#xff0c;然后在Vue项目中创建一个名为request.js的文件&#xff0c;用于封装axios实例。在这个文件中&#xff0c;可以设置默认的配置&#…

fastzdp_sqlmodel框架是如何实现更新和删除相关的功能封装的,20240817,Python的国产新ORM框架

根据模型对象更新 初步封装的方法 def update(engine, model_obj, update_dict):"""修改数据:param engine: 连接数据库的引擎对象:param model_obj: 模型对象:param update_dict: 更新字典:return:"""with Session(engine) as session:if not…

Git工具详细使用教程

Git工具详细使用教程 Git是一个分布式版本控制系统&#xff0c;它可以帮助你管理代码的历史记录。本教程将介绍如何使用Git工具进行基本的版本控制操作。 1. 安装Git 首先&#xff0c;你需要在你的计算机上安装Git。你可以从Git官方网站&#xff08;https://git-scm.com/&am…

MySQL(三)——DCL

文章目录 DCL用户管理查询用户创建用户修改用户密码删除用户 权限控制查询权限授予权限撤销权限 DCL DCL&#xff08;Data Control Language&#xff0c;数据控制语言&#xff09;是SQL的一个子集&#xff0c;专门用于定义数据库、表、视图等的访问权限和安全级别。 它允许数据…

Openstack二层网络的构建和使用

Openstack二层网络的构建和使用 一、实验目的 &#xff08;1&#xff09;了解网络层级、子网、动态地址、网关代理等概念并进行应用。 &#xff08;2&#xff09;了解OpenStack项目以及相关组件。 &#xff08;3&#xff09;了解 Neutron 二层网络的构建和使用。 二、实验原…

如何确定vtk .h文件所在的库名字

问题 例如使用class vtkSTLReader,头文件包含#include <vtkSTLReader.h>,库使用哪个&#xff1f; 解决 1.在vs2019解决方案资源管理器中搜索vtkSTLReader.cxx&#xff0c;显示project为IOGeometry即为库名 2.在所在的CMakeLists.txt追加库名 3.在cmake重新Configure、G…

JWT中的Token

1.JWT是什么&#xff1f; jwt&#xff08;json web token的缩写&#xff09;是一个开放标准&#xff08;rfc7519&#xff09;&#xff0c;它定义了一种紧凑的、自包含的方式&#xff0c;用于在各方之间以json对象安全地传输信息&#xff0c;此信息可以验证和信任&#xff0c;因…

如果大模型有信仰,那一定是“规模法则”

规模&#xff08;scale&#xff09;是除去时间、空间之外另一个重要的维度。规模缩放&#xff08;Scaling&#xff09;的过程中隐藏着世界非线性本质奥秘背后的共性——规模法则。结合伯努瓦曼德布洛特 Benoit Mandelbrot的《大自然的分形几何》、杰弗里韦斯特 Geoffery West 的…

面试官:Java虚拟机是什么,Java虚拟机的内存模型是什么样子的?

哈喽&#xff01;大家好&#xff0c;我是小奇&#xff0c;一个专给面试官添堵的撑序员 小奇打算以轻松幽默的对话方式来分享一些技术&#xff0c;如果你觉得通过小奇的文章学到了东西&#xff0c;那就给小奇一个赞吧 文章持续更新&#xff0c;可以微信搜索【小奇JAVA面试】第一…