Android配置透明度水印
qq377138858 人气:0今天对Android端水印进行了一个简单的优化,优化方式是对水印生成方式的修改。如图1修改为如图2。
我们先简单了解一下图一水印是如生成得。
//创建水印类构造方法 public MarkDrawable(String mMarkStr,int textColor,int textSize,int backgroundColor) { this.mMarkStr = mMarkStr; this.mTextColor=textColor; this.mTextSize=textSize; this.mBackgroundColor=backgroundColor; }
//创建paint实例绘制文字 mPaint=new TextPaint(); mPaint.setTextSize(mTextSize); mPaint.setAntiAlias(true); mPaint.setColor(mTextColor); final float width=mPaint.measureText(mMarkStr,0,mMarkStr.length())*2;
这里我们创建了文字绘制工具进行绘制文字
//绘制矩形 Rect rect=new Rect(); mPaint.getTextBounds(mMarkStr,0,mMarkStr.length(),rect); mBoundRect=new RectF(); //设置矩形得宽高 mBoundRect.set(0,0,(float) (width*Math.cos(Math.toRadians(mDegree) ))+inset,(float)(width*Math.sin(Math.toRadians(mDegree)))+inset); //在这里我们进行绘制矩形,为了设置单个水印的宽高
接着我们开始在画布上进行绘制
public void draw(Canvas canvas) { canvas.save(); canvas.drawColor(mBackgroundColor); canvas.translate(mBoundRect.width()/2,mBoundRect.height()/2); canvas.rotate(-mDegree); canvas.drawText(mMarkStr,inset/2-mBoundRect.width()/2,0,mPaint); canvas.restore(); }
绘制出一个带偏移角得文字
到这里我们前期工作完成绘制出了一个水印出来,现在我们需要将所有的水印铺满整个屏幕
//我们调用水印绘制得类 public WaterMarkDrawable(String markStr,int textColor,int textSize,int backgroundColor) { //在这里我们获取到单个水印得实体类 this.mMarkDrawable = new MarkDrawable(markStr,textColor,textSize,backgroundColor); //设置水印矩形 mBoundRect = new RectF(); //水印宽高 final int width=mMarkDrawable.getIntrinsicWidth(); final int height=mMarkDrawable.getIntrinsicHeight(); //将水印转成bitmap Bitmap bmp = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888); //将水印绘制到画布上 Canvas canvas = new Canvas(bmp); mMarkDrawable.setBounds(0,0,width,height);//用来确定绘制大小和位置 mMarkDrawable.draw(canvas); //利用bitmapshader类进行重复xy轴平铺 mShader = new BitmapShader(bmp, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);//基于绘制的第一个完成的bitmap,X轴Y轴方向重复的绘制bitmap mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//使位图抗锯齿的标志 mPaint.setStyle(Paint.Style.FILL);//填充 //设置paint得shader mPaint.setShader(mShader); }
在这里我们先将画出来的水印转成bitmaph后再将其绘制到画布上,最后利用BitmapShader进行xy轴进行重复平铺从而做到布满xy轴得需要,但到这里虽然平铺了,但是是整齐得平铺效果上并没有达到理想的效果如图所示:
我们主要谈谈第二种方式:
第二种方式,不用转成bitmap也没有用到BitmapShader重复平铺,而是利用暴力枚举进行对每一个x,y轴进行遍历对不同坐标上进行画水印。
public void draw(@NonNull Canvas canvas) { //获取屏幕宽度 int width = getBounds().right; //获取屏幕高度 int height = getBounds().bottom; //获取屏幕对角线 int diagonal = (int) Math.sqrt(width * width + height * height); // 对角线的长度 int Yspacing = 50; int XSpacing = 100; float textWidth; canvas.drawColor(0x00000000); canvas.rotate(mAngle); //文本宽度默认第一个文本 if (!ListUtils.isEmpty(mContent)){ if (StringUtils.isEmpty(mContent.get(0))){ return; } //设置文本的宽度从而做到文本宽度得不固定 textWidth = mPaint.measureText(mContent.get(0)); mes = mContent.get(0); }else{ if (StringUtils.isEmpty(mMessage)){ return; } //设置文本的宽度从而做到文本宽度得不固定 textWidth = mPaint.measureText(mMessage); mes = mMessage; } //为了统计当前在第几行从而实现错开显示 int index = 0; //记录当前的x轴坐标 float fromX; for (int positionY = diagonal / 10; positionY <= diagonal; positionY += (diagonal / 10+Yspacing)) { fromX = -width * 3 / 2 + (index++ % 2) * textWidth; // 上下两行的X轴起始点不一样,错开显示 int spacing = 0;//间距 for (float positionX = fromX; positionX < width; positionX += (textWidth * 2+XSpacing)) { canvas.drawText(mes, positionX, positionY , mPaint); } } canvas.save(); canvas.restore(); }
这种方式主要利用暴力枚举,y轴上在对角线比例高度得位置+间隔距离开始Y轴遍历;x轴上在初始位置,每次两倍字符串宽度+间隔得距离进行x轴开始遍历。最后铺满整个屏幕得到的效果为:
这样做到了上下两行得X轴起始点不一样,错开显示,实现界面美观。
在最后我们直接调用:(因为我们透明度调用了接口所以大家知道就好传入的参数为int型数据)
var alpha: Int = WaterMarkUtils.getChildrenBean(WaterMarkUtils.SCENE_SHOP)?.whiteTransparency!! * 255 / 100 binding.tvWaterMark.background = ( WaterMarkBg( this, WaterMarkUtils.getMarkName( WaterMarkUtils.getChildrenBean(WaterMarkUtils.SCENE_SHOP) ), -15, 14, Color.argb(alpha, 0, 0, 0), Typeface.DEFAULT_BOLD ) )
最终实现透明度配置。
加载全部内容