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

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

A102021987-55339.jpg_small.jpg 

A102024331-55340.png_small.png

之所以把这个写出来是因为在一个项目中需要用到这样的效果,我试过用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 extendsView {

PaintFlagsDrawFilter pfdf;

Paint paint;

Matrix matrix;

Bitmap bitmap;int index = -1;private intoriHeight;private intoriWidth;private intnewHeight;private intnewWidth;private int angle = 5;protected Path path = newPath();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, intdefStyle) {super(context, attrs, defStyle);

initCanvasInfo();

}publicRotateTextImageView(Context context, AttributeSet attrs) {super(context, attrs);

initCanvasInfo();

}publicRotateTextImageView(Context context) {super(context);

initCanvasInfo();

}/*** 初始化Paint*/

protected voidinitCanvasInfo() {

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

paint= newPaint();

paint.setAntiAlias(true);

matrix= newMatrix();

matrix.setRotate(5);

}

@Overrideprotected voidonDraw(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 voidcalculatePoints() {double a = angle * Math.PI / 180;

BigDecimal height= newBigDecimal(oriHeight);

BigDecimal width= newBigDecimal(oriWidth);

BigDecimal cos= newBigDecimal(Math.cos(a));

BigDecimal tan= newBigDecimal(Math.tan(a));

f[0] = 0;

f[1] =height.multiply(cos).floatValue();

f[2] = tan.multiply(newBigDecimal(shawHeight)).floatValue();

f[3] = (new BigDecimal(f[1])).subtract(newBigDecimal(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] = newBigDecimal(newHeight).floatValue();

}/*** 设置图片

*

*@parambmp*/

public voidsetBitmap(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();

}/*** 旋转角度

*

*@paramangle*/

public void setAngle(intangle) {this.angle =angle;

setBitmap(oriBitmap);

}/*** 设置底部阴影高度

*

*@paramshawHeight*/

public void setShawHeight(intshawHeight) {this.shawHeight =shawHeight;

postInvalidate();

}/*** 生成添加了白色边缘的图

*

*@parambmp

*@return

*/

protectedBitmap addFrame(Bitmap bmp) {

Bitmap bmpWithBorder= Bitmap.createBitmap(bmp.getWidth() +borderSize* 2, bmp.getHeight() + borderSize * 2, bmp.getConfig());

Canvas canvas= newCanvas(bmpWithBorder);

canvas.drawColor(Color.WHITE);

canvas.drawBitmap(bmp, borderSize, borderSize,null);returnbmpWithBorder;

}/*** 设置字符串

*

*@paramtext*/

public voidsetText(String text) {this.text =text;

postInvalidate();

}/*** 获取字体高度*/

protected intgetFontHeight() {

FontMetrics fm=paint.getFontMetrics();return (int) Math.ceil(fm.descent - fm.top) + 2;

}

}

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

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

View的使用

一、xml配置文件

android: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("这是一个测试");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值