android使用matrix控制图片的旋转,缩放

Android之matrix类控制图片的旋转、缩放、移动 在Android中,对图片的处理需要使用到Matrix类,Matrix是一个3 x 3的矩阵,他对图片的处理分为四个基本类型: 1、Translate————平移变换 2、Scale————缩放变换 3、Rotate————旋转变换 4、Skew————错切变换 在Android的API里对于每一种变换都提供了三种操作方式:set(用于设置Matrix中的值)、post(后乘,根据矩阵的 阅读详情

//实现如下效果
这里写图片描述

/** 
 * 使用矩阵控制图片移动、缩放、旋转 
 * @author 张进 
 */  
public class CommonImgEffectView extends View {  

    private Context context ;  
    private Bitmap mainBmp , controlBmp ;  
    private int mainBmpWidth , mainBmpHeight , controlBmpWidth , controlBmpHeight ;  
    private Matrix matrix ;   
    private float [] srcPs , dstPs ;  
    private RectF srcRect , dstRect ;  
    private Paint paint ,paintRect , paintFrame;  
    private float deltaX = 0, deltaY = 0; //位移值  
    private float scaleValue = 1; //缩放值  
    private Point lastPoint ;  
    private Point prePivot , lastPivot;  
    private float preDegree , lastDegree ;  
    private short currentSelectedPointindex;        //当前操作点击点  
    private Point symmetricPoint  = new Point();    //当前操作点对称点  

    /** 
     * 图片操作类型 
     */  
    public static final int OPER_DEFAULT = -1;      //默认  
    public static final int OPER_TRANSLATE = 0;     //移动  
    public static final int OPER_SCALE = 1;         //缩放  
    public static final int OPER_ROTATE = 2;        //旋转  
    public static final int OPER_SELECTED = 3;      //选择  
    public int lastOper = OPER_DEFAULT;  

    /* 图片控制点 
     * 0---1---2 
     * |       | 
     * 7   8   3 
     * |       | 
     * 6---5---4  
     */  
    public static final int CTR_NONE = -1;  
    public static final int CTR_LEFT_TOP = 0;  
    public static final int CTR_MID_TOP = 1;  
    public static final int CTR_RIGHT_TOP = 2;  
    public static final int CTR_RIGHT_MID = 3;  
    public static final int CTR_RIGHT_BOTTOM = 4;  
    public static final int CTR_MID_BOTTOM = 5;  
    public static final int CTR_LEFT_BOTTOM = 6;  
    public static final int CTR_LEFT_MID = 7;  
    public static final int CTR_MID_MID = 8;  
    public int current_ctr = CTR_NONE;  

    public CommonImgEffectView(Context context){  
        super(context);  
        this.context = context ;  
    }  

    public CommonImgEffectView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        this.context = context ;  
        initData();  
    }  

    /** 
     * 初始化数据 
     * @author 张进 
     */  
    private void initData(){  
        mainBmp = BitmapFactory.decodeResource(this.context.getResources(), R.drawable.flower);  
        controlBmp = BitmapFactory.decodeResource(this.context.getResources(), R.drawable.control);  
        mainBmpWidth = mainBmp.getWidth();  
        mainBmpHeight = mainBmp.getHeight();  
        controlBmpWidth = controlBmp.getWidth();  
        controlBmpHeight = controlBmp.getHeight();  

        srcPs = new float[]{  
                                0,0,   
                                mainBmpWidth/2,0,   
                                mainBmpWidth,0,   
                                mainBmpWidth,mainBmpHeight/2,  
                                mainBmpWidth,mainBmpHeight,   
                                mainBmpWidth/2,mainBmpHeight,   
                                0,mainBmpHeight,   
                                0,mainBmpHeight/2,   
                                mainBmpWidth/2,mainBmpHeight/2  
                            };  
        dstPs = srcPs.clone();  
        srcRect = new RectF(0, 0, mainBmpWidth, mainBmpHeight);  
        dstRect = new RectF();  

        matrix = new Matrix();  

        prePivot = new Point(mainBmpWidth/2, mainBmpHeight/2);  
        lastPivot = new Point(mainBmpWidth/2, mainBmpHeight/2);  

        lastPoint = new Point(0,0);  

        paint = new Paint();  

        paintRect = new Paint();  
        paintRect.setColor(Color.RED);  
        paintRect.setAlpha(100);  
        paintRect.setAntiAlias(true);  

        paintFrame = new Paint();  
        paintFrame.setColor(Color.GREEN);  
        paintFrame.setAntiAlias(true);  

        setMatrix(OPER_DEFAULT);  
    }  

    /** 
     * 矩阵变换,达到图形平移的目的 
     * @author 张进 
     */  
    private void setMatrix(int operationType){  
        switch (operationType) {  
        case OPER_TRANSLATE:  
            matrix.postTranslate(deltaX , deltaY);  
            break;  
        case OPER_SCALE:  
            matrix.postScale(scaleValue, scaleValue, symmetricPoint.x, symmetricPoint.y);  
            break;  
        case OPER_ROTATE:  
            matrix.postRotate(preDegree - lastDegree, dstPs[CTR_MID_MID * 2], dstPs[CTR_MID_MID * 2 + 1]);  
            break;  
        }  

        matrix.mapPoints(dstPs, srcPs);  
        matrix.mapRect(dstRect, srcRect);  
    }  

    private boolean isOnPic(int x , int y){  
        if(dstRect.contains(x, y)){  
            return true;  
        }else   
            return false;  
    }  

    private int getOperationType(MotionEvent event){  

        int evX = (int)event.getX();  
        int evY = (int)event.getY();  
        int curOper = lastOper;  
        switch(event.getAction()) {  
            case MotionEvent.ACTION_DOWN:  
                current_ctr = isOnCP(evX, evY);  
                Log.i("img", "current_ctr is "+current_ctr);  
                if(current_ctr != CTR_NONE || isOnPic(evX, evY)){  
                    curOper = OPER_SELECTED;  
                }  
                break;  
            case MotionEvent.ACTION_MOVE:  
                    if(current_ctr > CTR_NONE && current_ctr < CTR_MID_MID ){  
                        curOper = OPER_SCALE;  
                    }else if(current_ctr == CTR_MID_MID ){  
                        curOper = OPER_ROTATE;  
                    }else if(lastOper == OPER_SELECTED){  
                        curOper = OPER_TRANSLATE;  
                    }  
                break;  
            case MotionEvent.ACTION_UP:  
                curOper = OPER_SELECTED;  
                break;  
            default:  
                break;  
        }  
        Log.d("img", "curOper is "+curOper);  
        return curOper;  

    }  

     /** 
     * 判断点所在的控制点 
     * @param evX 
     * @param evY 
     * @return 
     */   
    private int isOnCP(int evx, int evy) {  
        Rect rect = new Rect(evx-controlBmpWidth/2,evy-controlBmpHeight/2,evx+controlBmpWidth/2,evy+controlBmpHeight/2);  
        int res = 0 ;  
        for (int i = 0; i < dstPs.length; i+=2) {  
            if(rect.contains((int)dstPs[i], (int)dstPs[i+1])){  
                return res ;  
            }  
            ++res ;   
        }  
        return CTR_NONE;  
    }  



    @Override  
    public boolean dispatchTouchEvent(MotionEvent event) {  
        int evX = (int)event.getX();  
        int evY = (int)event.getY();  

        int operType = OPER_DEFAULT;  
        operType = getOperationType(event);  

        switch (operType) {  
        case OPER_TRANSLATE:  
            translate(evX, evY);  
            break;  
        case OPER_SCALE:  
            scale(event);  
            break;  
        case OPER_ROTATE:  
            rotate(event);  
            break;  
        }  

        lastPoint.x = evX;  
        lastPoint.y = evY;    

        lastOper = operType;  
        invalidate();//重绘  
        return true;  
    }  

    /** 
     * 移动 
     * @param evx 
     * @param evy 
     * @author zhang_jin1 
     */  
    private void translate(int evx , int evy){  

        prePivot.x += evx - lastPoint.x;  
        prePivot.y += evy -lastPoint.y;  

        deltaX = prePivot.x - lastPivot.x;  
        deltaY = prePivot.y - lastPivot.y;  

        lastPivot.x = prePivot.x;  
        lastPivot.y = prePivot.y;  

        setMatrix(OPER_TRANSLATE); //设置矩阵  

    }  

    /** 
     * 缩放 
     * 0---1---2 
     * |       | 
     * 7   8   3 
     * |       | 
     * 6---5---4 
     * @param evX 
     * @param evY 
     */  
    private void scale(MotionEvent event) {  

        int pointIndex = current_ctr*2 ;  

        float px = dstPs[pointIndex];  
        float py = dstPs[pointIndex+1];  

        float evx = event.getX();  
        float evy = event.getY();  

        float oppositeX = 0 ;  
        float oppositeY = 0 ;  
        if(current_ctr<4 && current_ctr >= 0){  
             oppositeX = dstPs[pointIndex+8];  
             oppositeY = dstPs[pointIndex+9];  
        }else if(current_ctr >= 4){  
             oppositeX = dstPs[pointIndex-8];  
             oppositeY = dstPs[pointIndex-7];  
        }  
        float temp1 = getDistanceOfTwoPoints(px,py,oppositeX,oppositeY);  
        float temp2 = getDistanceOfTwoPoints(evx,evy,oppositeX,oppositeY);  

        this.scaleValue = temp2 / temp1 ;  
        symmetricPoint.x = (int) oppositeX;  
        symmetricPoint.y = (int)oppositeY;  

        Log.i("img", "scaleValue is "+scaleValue);  
        setMatrix(OPER_SCALE);  
    }  

    /** 
     * 旋转图片 
     * 0---1---2 
     * |       | 
     * 7   8   3 
     * |       | 
     * 6---5---4  
     * @param evX 
     * @param evY 
     */  
    private void rotate(MotionEvent event) {  

        if(event.getPointerCount() == 2){  
            preDegree = computeDegree(new Point((int)event.getX(0), (int)event.getY(0)), new Point((int)event.getX(1), (int)event.getY(1)));  
        }else{  
            preDegree = computeDegree(new Point((int)event.getX(), (int)event.getY()), new Point((int)dstPs[16], (int)dstPs[17]));  
        }  
        setMatrix(OPER_ROTATE);  
        lastDegree = preDegree;  
    }  


    /** 
     * 计算两点与垂直方向夹角 
     * @param p1 
     * @param p2 
     * @return 
     */  
    public float computeDegree(Point p1, Point p2){  
        float tran_x = p1.x - p2.x;  
        float tran_y = p1.y - p2.y;  
        float degree = 0.0f;  
        float angle = (float)(Math.asin(tran_x/Math.sqrt(tran_x*tran_x + tran_y* tran_y))*180/Math.PI);  
        if(!Float.isNaN(angle)){  
            if(tran_x >= 0 && tran_y <= 0){//第一象限  
                degree = angle;  
            }else if(tran_x <= 0 && tran_y <= 0){//第二象限  
                degree = angle;  
            }else if(tran_x <= 0 && tran_y >= 0){//第三象限  
                degree = -180 - angle;  
            }else if(tran_x >= 0 && tran_y >= 0){//第四象限  
                degree = 180 - angle;  
            }  
        }  
        return degree;  
    }  

    /** 
     * 计算两个点之间的距离 
     * @param p1 
     * @param p2 
     * @return 
     */  
    private float getDistanceOfTwoPoints(Point p1, Point p2){  
        return (float)(Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)));  
    }  

    private float getDistanceOfTwoPoints(float x1,float y1,float x2,float y2){  
        return (float)(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));  
    }  


    @Override  
    public void onDraw(Canvas canvas){  
        drawBackground(canvas);//绘制背景,以便测试矩形的映射  
        canvas.drawBitmap(mainBmp, matrix, paint);//绘制主图片  
        drawFrame(canvas);//绘制边框,以便测试点的映射  
        drawControlPoints(canvas);//绘制控制点图片  
    }  

    private void drawBackground(Canvas canvas){  
        canvas.drawRect(dstRect, paintRect);  
    }  

    private void drawFrame(Canvas canvas){  
        canvas.drawLine(dstPs[0], dstPs[1], dstPs[4], dstPs[5], paintFrame);  
        canvas.drawLine(dstPs[4], dstPs[5], dstPs[8], dstPs[9], paintFrame);  
        canvas.drawLine(dstPs[8], dstPs[9], dstPs[12], dstPs[13], paintFrame);  
        canvas.drawLine(dstPs[0], dstPs[1], dstPs[12], dstPs[13], paintFrame);  
        canvas.drawPoint(dstPs[16], dstPs[17], paintFrame);  
    }  

    private void drawControlPoints(Canvas canvas){  

        for (int i = 0; i < dstPs.length; i+=2) {  
            canvas.drawBitmap(controlBmp, dstPs[i]-controlBmpWidth/2, dstPs[i+1]-controlBmpHeight/2, paint);  
        }  

    }  

}  
android 利用matrix实现图片的旋转与缩放 一个简单的demo。使用android中的matrix属性,实现图片的放大、缩小、以及左旋转、右旋转。 立即下载

相关推荐

android中手动处理屏幕旋转问题

在开发Android应用的过程中,我们都会遇到屏幕旋转的情况。 在旋转的过程中,默认会将Activity销毁,然后再重新创建, 这会严重影响应用的性能。 如果没有自行修改的话,在配置变化时,Android会结束当前 的Activity实例,然后重新创建一个适用于新配置的Activity 。这会带来性能上的损失,因为这需要先保存UI状态,然后再 完全重新构建UI。

Android:使用Matrix控制变换

一、使用Matrix控制变换  Matrix是Android提供的一个矩阵工具类,本身不能对图像或组件进行变换,但它可以和其它API结合起来控制图形、组件的变换;  Matrix提供了如下方法来控制平移、旋转和缩放:  setTranslate(float dx,float dy):控制Matrix进行平移;  setSkew(float kx,fl

1024工场 1万+

点击按钮使图片旋转

通过点击按钮可以使图片旋转90度,再次点击回到原样。

osg 矩阵的平移缩放旋转(转)

平移旋转缩放这个三个是osg矩阵操作中,最常见的操作,下面给出示例以及说明 首先先了解下osg空间方向:  osg方向如左图所示,x轴表示屏幕水平方向,y轴表示和屏幕垂直方向即屏幕里面方向,z轴表示屏幕垂直方向,每个箭头指向表示正方向  下面来学习矩阵变换操作 首先平移:   #includeosgDB/ReadFile> #includeosgViewe

qq_37802138的博客 1612

android 动态旋转图片 Bitmap与Matrix旋转ImageView

android 动态旋转图片 Bitmap与Matrix旋转ImageView

Android开发图片水平旋转180度方法

今天小编就为大家分享一篇Android开发图片水平旋转180度方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

Matrix控制平移、旋转和缩放的方法

1、setTranslate(float ds,float dy):控制Matrix进行平移。 2、setSkew(float kx,float ky,float px,float py):控制Matrix以px、py为轴心进行倾斜。kx、ky为X、Y方向上的倾斜距离。 3、setSkew(float kx,float ky):控制Matrix进行倾斜。kx、ky为X、Y方向上的倾斜距离。

ahao214——Dreamspace 2207

postman响应体:“msg“: “请求缺失签名Sign“、 “msg“: “请求缺失时间戳“

请求标头有Sign、Timestamp,但是直接将网址复制到postman时,Headers没有自动生成这两个参数,所以运行时会报错。

m0_46862648的博客 1706

android matrix 实现点击旋转,Android中利用matrix 控制图片的旋转、缩放、移动

本文主要讲解利用android中Matrix控制图形的旋转缩放移动,具体参见一下代码:/*** 使用矩阵控制图片移动、缩放、旋转*/public class CommonImgEffectView extends View {private Context context ;private Bitmap mainBmp , controlBmp ;private int mainBmpWidth ...

weixin_30969157的博客 1157

Langchain4j 文档处理实战:从加载到分割的完整流程解析

本文详细解析了使用Langchain4j进行文档处理的完整流程,涵盖从文档加载、解析到分割的核心步骤。通过实战代码示例,重点介绍了如何利用文档分割器将大文档切割为适合大语言模型处理的片段,并提供了参数调优与避坑指南,帮助Java开发者高效构建AI应用的数据处理基础。

smartcontract5的博客 543

【GAMES101】现代计算机图形学入门 资料整理

课程网址 课程主页 包括ppt 课程PPT和视频 一篇搞定!GAMES101现代计算机图形学入门(全) 作业链接地址 作业论坛 GAMES101课程环境搭建(Win10+VSCode) 计算机图形学笔记 虎书pdf 提取:n2rx 【必须】:高等数学(微积分、线性代数)、算法、数据结构 【非必须】:信号处理、数值分析、大学物理(光学) 在线公式编辑器 一定要做作业,如果个人要配置环境的话应该是配置opencv,eigen这两个核心库就行了,目前觉得最核心的一个作业是作业3,实现着色器和渲染管线,做完一遍

ysh的博客 2684

Android matrix 控制图片的旋转、缩放、移动

本文主要讲解利用android中Matrix控制图形的旋转缩放移动,具体参见一下代码: /** * 使用矩阵控制图片移动、缩放、旋转 * @author 张进 */ public class CommonImgEffectView extends View {     private Context context ;     private Bitmap mainBmp ,

张进の专栏 30万+

A-Level CS 计算机科学 考试知识点——考试介绍&第1章

前言:该系列文章是本人在给学生辅导本课程的过程中结合英文教材所总结的,该系列共分为30章,主要介绍了考试的核心知识点。若需要A-Level CS 计算机科学考试辅导也可以私信我。 目录 关于A-Level CS 计算机科学考试 考试简介 考试内容 考试时间 评分情况 第1章 信息表示 本章学习内容 1.01 数字系统 1.02 数字的内部编码 整数编码(Coding for integers) 二进制编码的十进制(Binary coded decimal——BCD) 1.03.

王俊的博客 6458

android Matrix类控制图片 View的移动、缩放、旋转、错切

对图片或View组件的处理需要使用到Matrix类,Matrix是一个3 x 3的矩阵工具类,它对图片或图片或View组件的处理分为 Matrix旋转等操作主要针对图片的X轴Y轴上面的操作 四个基本类型: 1、Translate————平移变换 2、Scale————缩放变换 3、Rotate————旋转变换 4、Skew————错切变换 set pre post方法总结 set方法

写博客只为学习 2713

PaddleOCR实战:从零开始训练自己的OCR模型(附完整代码与数据集处理技巧)

本文提供了一份详尽的PaddleOCR实战指南,手把手教你从零开始训练专属的OCR模型。内容涵盖高质量训练数据的准备与标注技巧、预训练模型的选型对比、关键参数调优策略,并附有完整的代码示例。通过遵循本文的步骤,开发者可以高效构建并优化贴合自身业务场景的高精度OCR模型,实现从数据到部署的全流程掌握。

weixin_29263201的博客 570

HFSS螺旋线圈的优化设计与高效仿真实践

本文详细介绍了HFSS螺旋线圈的优化设计与高效仿真实践,涵盖核心参数设置、参数化建模、仿真加速技巧及结果分析。通过HFSS软件实现螺旋线圈的高效仿真,特别适用于无线充电和RFID系统设计,提升设计效率与性能验证准确性。

weixin_30235225的博客 445

旋转比例不变 android,android Matrix类控制图片 View的移动、缩放、旋转、错切

[b]对图片或View组件的处理需要使用到[/b][size=medium][color=red]Matrix[/color][/size]类,[b]Matrix是一个3 x 3的矩阵工具类[/b],[b]它对图片或图片或View组件的处理分为[/b][color=blue][size=medium][b]Matrix旋转等操作主要针对图片的X轴Y轴上面的操作[/b][/size][/color]...

weixin_28914101的博客 425

从 SAP ABAP 到 S/4HANA,SAML 2.0 单点登录到底是怎么跑起来的

在很多 SAP 项目里,SSO 不是一个锦上添花的功能,而是系统能不能顺利上线的基本门槛。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1050
上一篇: android手机锁屏
下一篇: Android 自定义RecyclerView 实现真正的Gallery效果
偶像宣言
博客等级 码龄11年 14粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值