Android 裁剪 几何变换

这篇具有很好参考价值的文章主要介绍了Android 裁剪 几何变换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

canvas.clipRect(left , top ,right,bottom) 裁切函数

canvas.clipPath() // 切割图形

clipOutRect / clipOutPath 切出,切出的是不需要的

clipPath(path) 切出来会有毛边 锯齿,会把指定范围的显示出来,其他的不显示,按像素px进行裁切

如果需要精细显示 可以使用xfermode

canvas 几何变换(改变坐标系)

translate (x,y) 平移 

rotate(degree) 指定角度旋转

scale(x,y) 缩/放

skew(x,y) 侧切

canvas.tranlate

canvas.drawXXX  先变换 移动 再绘制

canvas.rotate

canvas.translate 先旋转再平移,平移不是按照原先的坐标移动 而是沿着旋转方向的x y 移动

这些操作的是canvas

canvas.scale

canvas.drawXXX 先放缩,然后绘制,绘制时放缩后的位置

Matrix 的几何变换

相比于canvas  它有两套写法 比如 preScale  = canvas.scale /postScale

post 基于变换前的坐标系进行变换

Camera类:

rotate(x,y,z) 旋转 // 旋转最好指定轴心,没有轴心默认会是0,0位置

rotateX

rotateY

rotateZ

三维坐标,X不变,Y轴往上是正向,Z轴为交互点,相当于投影

camera.applyToCanvas(canvas) 绑定
canvas.translate
camera.applyToCanvas(canvas)
canvas.translate

先移动canvas 然后 camera完成后 再移动回来 得到正形 ,思路得相反,canvas 轴心会变换

示例:

canvas.translate(BITMAP_PADDING + BITMAP_SIZE /2, BITMAP_PADDING + BITMAP_SIZE /2, )
camera.applyToCanvas(canvas)
canvas.translate(- (BITMAP_PADDING + BITMAP_SIZE /2),- (BITMAP_PADDING + BITMAP_SIZE /2), ) 

会出现弧形效果 需要改变camera的Z值

camera.setLocation(x,y,z)  z默认-8f  英寸为单位 1英寸= 72像素

手机像素不同,所需要调整的Z轴调整的也不同 需要动态计算

clipRect 裁切需要判断是否进行三维变化或者canvas的x y 是否已经变换

cli[pRect后,只保留裁切的,其他的内容都会丢弃,代码也就执行失效,需要canvas.save文章来源地址https://www.toymoban.com/news/detail-680863.html

package com.example.androidstudiogiraffe.view

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Camera
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.View
import com.example.androidstudiogiraffe.R
import com.future.startstudyproject.utils.dp

private val BITMAP_SIZE = 200.dp
private val BITMAP_PADDING = 100.dp


class CameraView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val bitmap = getBitmap(BITMAP_SIZE.toInt())
    private val camera = Camera()


    private val path = Path().apply {
        addOval(
            BITMAP_PADDING, BITMAP_PADDING, BITMAP_PADDING + BITMAP_SIZE,
            BITMAP_PADDING + BITMAP_SIZE, Path.Direction.CCW
        )
    }


    init {
        camera.rotateX(12f)
        camera.setLocation(0f, 0f, -6 * resources.displayMetrics.density)
    }

    override fun onDraw(canvas: Canvas) {

//        canvas.clipRect(BITMAP_PADDING, BITMAP_PADDING, BITMAP_PADDING + BITMAP_SIZE /2 .toFloat() ,
//            BITMAP_PADDING + BITMAP_SIZE / 2 .toFloat())
//        canvas.clipPath(path)

        //上
        canvas.save()
        canvas.translate(BITMAP_PADDING + BITMAP_SIZE / 2, BITMAP_PADDING + BITMAP_SIZE / 2)
        canvas.rotate(-30f) //旋转回来

        //旋转
//        canvas.clipRect(
//            -BITMAP_SIZE / 2,
//            -BITMAP_SIZE / 2,
//            BITMAP_SIZE / 2,
//             0f
//        )

        //未旋转
        canvas.clipRect(
            -BITMAP_SIZE ,
            -BITMAP_SIZE,
            BITMAP_SIZE,
            0f
        )
        canvas.rotate(30f) //旋转30度
        canvas.translate(-(BITMAP_PADDING + BITMAP_SIZE / 2), -(BITMAP_PADDING + BITMAP_SIZE / 2))
        canvas.drawBitmap(bitmap, BITMAP_PADDING, BITMAP_PADDING, paint)
        canvas.restore()

        //下
        canvas.save()
        canvas.translate(BITMAP_PADDING + BITMAP_SIZE / 2, BITMAP_PADDING + BITMAP_SIZE / 2)
        canvas.rotate(-30f) //旋转回来
        camera.applyToCanvas(canvas)

//        canvas.clipRect(
//            -BITMAP_SIZE / 2,
//            0f,
//            BITMAP_SIZE / 2,
//            BITMAP_SIZE / 2
//        )

        //未旋转
        canvas.clipRect(
            -BITMAP_SIZE ,
            0f,
            BITMAP_SIZE,
            BITMAP_SIZE
        )
        canvas.rotate(30f) //旋转30度
        canvas.translate(-(BITMAP_PADDING + BITMAP_SIZE / 2), -(BITMAP_PADDING + BITMAP_SIZE / 2))
        canvas.drawBitmap(bitmap, BITMAP_PADDING, BITMAP_PADDING, paint)
        canvas.restore()
    }

    private fun getBitmap(width: Int): Bitmap {
        val option = BitmapFactory.Options()
        option.inJustDecodeBounds = true
        BitmapFactory.decodeResource(resources, R.drawable.head_image, option)
        option.inJustDecodeBounds = false
        option.inDensity = option.outWidth
        option.inTargetDensity = width
        return BitmapFactory.decodeResource(resources, R.drawable.head_image, option)
    }
}

到了这里,关于Android 裁剪 几何变换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • RK3568 Android 13 系统裁剪

    RK3568 Android 13 系统裁剪

    android 13 系统裁剪是个大工程,裁剪也是需要大量的测试,才能保证系统的稳定性,以下是RK官方给出的裁剪方案,有兴趣的可以去看一下,对裁剪不是要求过高的可以根据官方的建议,对系统进行裁剪: Rockchip Android平台内存优化及系统裁剪_build_with_go_opt-CSDN博客 然后官方的裁

    2024年02月22日
    浏览(46)
  • Android 设置头像(拍照获取、相册获取、裁剪照片)

         在Android原生态开发过程中,往往会设计到用户头像的设置问题,一般来讲设置头像需要用到拍照、获取照片、存储照片、裁剪照片、显示照片等问题,本文将一步一步的进行说明讲解。 首先需要强调几点我在开发过程中遇到的问题。 权限问题,在Android6.0以后,Andr

    2024年02月13日
    浏览(16)
  • Android 华为手机荣耀8X调用系统裁剪工具不能裁剪方形图片,裁剪后程序就奔溃,裁剪后获取不到bitmap的问题

    买了个华为荣耀8X,安装自己写的App后,调用系统裁剪工具发现裁剪是圆形的,解决办法: 解决选择裁剪图片,每次无论怎么选,都是同一张图片的问题,解决方法如下: 在裁剪图片的方法里加上如下判断, 主要是要让return-data为false 点击确定裁剪那个对号(√)时,程序就

    2024年02月11日
    浏览(32)
  • Canvas中的裁剪师讲解与实战——Android高级UI(1),Android体系化进阶学习图谱

    Canvas中的裁剪师讲解与实战——Android高级UI(1),Android体系化进阶学习图谱

    从今天开始我们聊一聊 Canvas 的API,因为Canvas的API较多,所以我们分为几次分享,首先分享的是裁剪类型的API使用。话不多说,先上实战图。 老夫的少女心 源码地址文末会给出,了解原理才能更好地驾驭。 分享前,我们先来聊聊,在我们生活中如何绘制一张如下的图。 我们

    2024年04月13日
    浏览(23)
  • Canvas中的裁剪师讲解与实战——Android高级UI

    Canvas中的裁剪师讲解与实战——Android高级UI

    绘图坐标系:决定我们的绘制的坐标 视图坐标系:决定我们所看到的画布范围 Canvas 中以 clip开头 的公有方法,用于裁剪画布的内容。 我们抽取比较好玩的参数类型为Path的方法来分享,其余的都可以一一映射进来。 1、clipPath public boolean clipPath(@NonNull Path path) 描述: 只留下

    2024年04月17日
    浏览(12)
  • Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

    Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

           在项目研发中,相信大家都遇到过给用户增加 头像照片 的需求。        随着 手机版本的不断更新 ,android 8、android 9、android 10、android 12、android 13、鸿蒙系统等等;遇到这个功能需求,大家肯定会想, “这还不好写? 之前就已经写过了。” 把老项目跑了一遍

    2024年02月01日
    浏览(9)
  • Android初学之android studio运行java/kotlin程序

    Android初学之android studio运行java/kotlin程序

    第一步骤: File — New — New Module ,然后弹出一个框,(左边)选择 Java or Kotlin Library ,(右边)编辑自己的图书馆名、包名、类名,选择 Java 一个语言,然后 Finish 如下图: 然后,就可以看见我新建的 java Library 了,如下图: 第二步骤:马上写个测试程序 看看能不能运行

    2024年02月11日
    浏览(12)
  • Android---Kotlin 学习009

    Android---Kotlin 学习009

    在 java 里如果一个类没有被 final 修饰,那么它都是可以被继承的。而在 kotlin 中,类默认都是封闭的,要让某个类开放继承,必须使用 open 修饰它,否则会编译报错。此外在子类中,如果要复写父类的某个方法,需要用到 Override (在 kt 中就不是注解了)

    2024年02月01日
    浏览(12)
  • Android Kotlin 协程初探

    维基百科:协程,英文Coroutine [kəru’tin] (可入厅),是计算机程序的一类组件,推广了协作式多任务的子程序,允许执行被挂起与被恢复。 作为Google钦定的Android开发首选语言Kotlin,协程并不是 Kotlin 提出来的新概念,目前有协程概念的编程语言有Lua语言、Python语言、Go语言

    2024年02月08日
    浏览(14)
  • Android AlertDialog setView,kotlin

    Android AlertDialog setView,kotlin             Android DialogFragment(1)_zhangphil的博客-CSDN博客 Android DialogFragment(1)和过去的AlertDialog类似,Android引入的DialogFragment旨在为开发者提供一个“富”dialog,而不必受到过去Android AlertDialog的局限。首先,DialogFragment是一个Fragment,它有Fragm

    2024年02月13日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包