先看看图片的效果,左边是原图,右边是旋转之后的图;

 

之所以把这个写出来是因为在一个项目中需要用到这样的效果,我试过用FrameLayout布局如上的画面,然后旋转FrameLayout,随之而来也就存在了一些问题——锯齿!

在网上搜索之后,有两种方法,一是利用Paint,二是利用Canvas;
(1)、paint.setAntiAlias(true);

   paint.setFlags(Paint.ANTI_ALIAS_FLAG);

(2)、DrawFilter pfdf = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);

   canvas.setDrawFilter(pfdf);

而如果利用paint,或者canvas,需要从哪获取paint/canvas,这也是一个问题;

在实现的过程中,尝试过自定义FrameLayout下面的单个View{ImageView,TextView},但都以失败告终,失败的主要问题在于右图下边的文字描述无法和相片边框相对齐,而且用Matrix旋转背景之后背景大小改变,位置也不在最下边,所以就采用了单独实现一个View的方法,主要原因还是因为自身对Canvas绘图及Paint画笔不是很熟悉,所以导致的效率不高;

public class RotateTextImageView extends View {PaintFlagsDrawFilter pfdf;Paint paint;Matrix matrix;Bitmap bitmap;int index = -1;private int oriHeight;private int oriWidth;private int newHeight;private int newWidth;private int angle = 5;protected Path path = new Path();private float[] f = new float[8];private int shawHeight = 20;private int borderSize = 8;Bitmap oriBitmap;private String text = "";public RotateTextImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initCanvasInfo();}public RotateTextImageView(Context context, AttributeSet attrs) {super(context, attrs);initCanvasInfo();}public RotateTextImageView(Context context) {super(context);initCanvasInfo();}/*** 初始化Paint*/protected void initCanvasInfo() {pfdf = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG| Paint.FILTER_BITMAP_FLAG);paint = new Paint();paint.setAntiAlias(true);matrix = new Matrix();matrix.setRotate(5);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);paint.reset();// 消除锯齿paint.setAntiAlias(true);paint.setFlags(Paint.ANTI_ALIAS_FLAG);canvas.setDrawFilter(pfdf);canvas.drawBitmap(bitmap, 0, 0, paint);newHeight = bitmap.getHeight();newWidth = bitmap.getWidth();calculatePoints();// 添加阴影
        path.reset();path.moveTo(f[0], f[1]);path.lineTo(f[2], f[3]);path.lineTo(f[4], f[5]);path.lineTo(f[6], f[7]);path.close();paint.setStyle(Paint.Style.FILL_AND_STROKE);paint.setColor(Color.parseColor("#96ffffff"));canvas.drawPath(path, paint);// 添加字符if (text != null && !text.equals("")) {path.reset();paint.setTextSize(18);float width = paint.measureText(text);path.moveTo((f[0] + f[2]) / 2, (f[1] + f[3]) / 2);path.lineTo((f[4] + f[6]) / 2, (f[5] + f[7]) / 2);paint.setColor(Color.parseColor("#2b2b2b"));canvas.drawTextOnPath(text, path, (oriWidth - width) / 2, 3, paint);}layout(0, 0, newWidth, newHeight);}/*** 计算坐标值*/private void calculatePoints() {double a = angle * Math.PI / 180;BigDecimal height = new BigDecimal(oriHeight);BigDecimal width = new BigDecimal(oriWidth);BigDecimal cos = new BigDecimal(Math.cos(a));BigDecimal tan = new BigDecimal(Math.tan(a));f[0] = 0;f[1] = height.multiply(cos).floatValue();f[2] = tan.multiply(new BigDecimal(shawHeight)).floatValue();f[3] = (new BigDecimal(f[1])).subtract(new BigDecimal(shawHeight)).floatValue();f[4] = width.multiply(cos).add(new BigDecimal(f[2])).floatValue();f[5] = new BigDecimal(newHeight - shawHeight).floatValue();f[6] = width.multiply(cos).floatValue();f[7] = new BigDecimal(newHeight).floatValue();}/*** 设置图片* * @param bmp*/public void setBitmap(Bitmap bmp) {oriBitmap = bmp;matrix.reset();matrix.setRotate(angle);Bitmap bitmapF = addFrame(bmp);oriHeight = bitmapF.getHeight();oriWidth = bitmapF.getWidth();bitmap = Bitmap.createBitmap(bitmapF, 0, 0, bitmapF.getWidth(),bitmapF.getHeight(), matrix, true);postInvalidate();}/*** 旋转角度* * @param angle*/public void setAngle(int angle) {this.angle = angle;setBitmap(oriBitmap);}/*** 设置底部阴影高度* * @param shawHeight*/public void setShawHeight(int shawHeight) {this.shawHeight = shawHeight;postInvalidate();}/*** 生成添加了白色边缘的图* * @param bmp* @return*/protected Bitmap addFrame(Bitmap bmp) {Bitmap bmpWithBorder = Bitmap.createBitmap(bmp.getWidth() + borderSize* 2, bmp.getHeight() + borderSize * 2, bmp.getConfig());Canvas canvas = new Canvas(bmpWithBorder);canvas.drawColor(Color.WHITE);canvas.drawBitmap(bmp, borderSize, borderSize, null);return bmpWithBorder;}/*** 设置字符串* * @param text*/public void setText(String text) {this.text = text;postInvalidate();}/*** 获取字体高度*/protected int getFontHeight() {FontMetrics fm = paint.getFontMetrics();return (int) Math.ceil(fm.descent - fm.top) + 2;}
}

  代码解释:其实没有什么难的东西,只是一些数学运算,代码中每一个方法都有对应的功能注释。浮点型数组代表阴影层四个坐标点的八个坐标值,分别是左下、左上、右上、右下四个点,阴影层坐标计算也比较简单,但有点繁琐,就是把原图旋转之后再根据几何知识进行求解坐标!

  每次重新设置角度,设置图片,都需要重新绘制图形-->postInvalidate();

View的使用

一、xml配置文件

    <com.livingstone.RotateTextImageViewandroid:id="@+id/myview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:minHeight="250dip"android:minWidth="200dip"android:paddingLeft="5dip" />

二、设置文字说明及角度、图片

        RotateTextImageView myView = (RotateTextImageView) findViewById(R.id.myview);myView.setShawHeight(50);Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.test1);myView.setBitmap(bmp);myView.setAngle(10);myView.setText("这是一个测试");

Ex:获取字体宽度的两种方法
<1>.通过paint获取字体的Rect

Rect rect=newRect();
paint.getTextBounds("你好",0,1, rect);
Log.v("a:","height:"+rect.height()+"width:"+rect.width());

<2>.通过paint直接获取字体宽度

intwidth=(int)paint.measureText("你好",0,1);
Log.v("width:","width:"+width);

转载于:https://www.cnblogs.com/a284628487/p/3377925.html

Android 自定义View消除锯齿实现图片旋转,添加边框及文字说明相关推荐

  1. Android 自定义View 圆形圆角图片

    [Android 自定义View 圆形圆角图片] 基于Xfermode 实现 1.概述 在很久以前也写过一个利用Xfermode 实现圆形.圆角图片的(Android 完美实现图片圆角和圆形(对实现进 ...

  2. Android 自定义拍照,解决图片旋转,拍照参数设置兼容问题

    Android 自定义拍照,解决图片旋转,拍照参数设置兼容问题 参考文章: (1)Android 自定义拍照,解决图片旋转,拍照参数设置兼容问题 (2)https://www.cnblogs.com/ ...

  3. android 自定义view 加载图片,Android自定义View基础开发之图片加载进度条

    学会了Paint,Canvas的基本用法之后,我们就可以动手开始实践了,先写个简单的图片加载进度条看看. 按照惯例,先看效果图,再决定要不要往下看: 既然看到这里了,应该是想了解这个图片加载进度条了, ...

  4. android旋转不重绘,Android自定义view仿微信刷新旋转小风车

    本文实例为大家分享了Android仿微信刷新旋转小风车 具体代码,供大家参考,具体内容如下 不太会录像,没办法,智能截图了 不多说了,直接上代码 package com.shipneg.demoysp ...

  5. imageview 自定义 android,Android自定义ImageView实现在图片上添加图层效果

    首先我们先看下效果图 实现思路 这是两张前后对比图,右边第二张图里面的已抢光标签图片当已经没有商品的时候就会显示了,在每个图片的中心位置,第一想法是在ImageView的外层再套一层RelativeL ...

  6. Android 自定义View之3D骰子旋转

    你可以指定立方体中每一面骰子的点数,颜色和背景,同时也可以指定执行的动画时间和动画插值器 更多有趣的view 使用 在根目录的build.gradle添加这一句代码: allprojects {rep ...

  7. 图片如何加边框和文字?试试下面这三个方法吧

    前几天和朋友出去玩的时候,由于好久没见,拍摄了许多的大合照.在准备将照片发朋友圈的时候,我们希望可以给图片添加上文字和边框,让照片看起来更加美观.于是我就花了点时间上网搜索了几个怎么给图片加上边框和文 ...

  8. Android自定义View(七)_Canvas之图片文字

    在上一篇文章Canvas之画布操作中我们了解了画布的一些基本操作方法,本次了解一些绘制图片文字相关的内容.如果你对前几篇文章讲述的内容熟练掌握的话,那么恭喜你,本篇结束之后,大部分的自定义View已经 ...

  9. Android绘图机制(二)——自定义View绘制形, 圆形, 三角形, 扇形, 椭圆, 曲线,文字和图片的坐标讲解

    Android绘图机制(二)--自定义View绘制形, 圆形, 三角形, 扇形, 椭圆, 曲线,文字和图片的坐标讲解 我们要想画好一些炫酷的View,首先我们得知道怎么去画一些基础的图案,比如矩形,圆 ...

最新文章

  1. C++建立动态二维数组
  2. mysql批量插入:语法
  3. 【虚拟化】docker安装ElasticSearch+Kibana,下载IK分词器
  4. 今天一早来打开IDEA,全面飘红,所有的含有import语句的文件都会报错
  5. 他在 B 站有 178 万粉丝,今天免费带你玩转 Python
  6. 专访香侬科技:致力于让世界听到中文NLP的声音
  7. Day 5 20190120 老男孩python学习第5天 内容整理
  8. Zabbix、Nagios、Open-Falcon 等开源监控,都能对接的Saas 电话告警平台
  9. 浏览器打印设置横向打印_震旦打印机如何设置认证打印
  10. Android中调用文件管理器进行选择文件(记录)
  11. html泰勒展开,【转载】泰勒展开式
  12. 虚拟机linux装无线网卡驱动,linux无线网卡驱动安装
  13. LVS高性能原因揭秘
  14. 使用Modern UI for WPF的导航功能
  15. 汉语语法和英语语法的区别
  16. 电子邮件协议---SMTP,POP3,IMAP,MIME
  17. 苹果开放降级通道_苹果出手,关闭降级系统iOS13验证,iOS14再也回不去了!
  18. androidstudio虚拟机打不开的解决方法,一路坎坷,靠运气成功的!!!
  19. ROS 机器人操作系统
  20. IC卡·一卡一密加密 动态数据防伪方案实现

热门文章

  1. HDU4417 Super Mario 主席树
  2. 9,线程池 threadPool 与 线程池执行器 threadPoolExecutor
  3. 网站开发与客户之间的流程
  4. C# Marshal的使用,非托管内存中分配内存注意的问题
  5. MFC通过对话框窗口句柄获得对话框对象指针
  6. C++中的“error:LNK2005 已经在*.obj中定义”异常
  7. 配置文件configSections节点使用实例      。
  8. Python—实训day2—爬虫案例1:访问百度贴吧
  9. Xcode12.5最新快捷键的使用(学会事半功倍)
  10. 如何处理几十万条并发数据_Swoole 如何处理高并发以及异步 I/O 的实现