-
先看效果动图
-
上面动图比较糊,可以看下面的部分截图
image.png
- 主要是采用canvas的clipPath实现,不是很复杂,主要动态计算哈坐标就行,工程不大,就直接贴代码了,如下:
class MainActivity : AppCompatActivity() {
private val PREFS_FILE = "device_id.xml"
private val PREFS_DEVICE_ID = "device_id"
private var uuid: UUID? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<View>(R.id.onePicBtn).setOnClickListener {
findViewById<ImageView>(R.id.testImgV).setImageBitmap(Utils.compoundBitmap(this, true, 300, true, 200, findViewById<CheckBox>(R.id.isArcFg).isChecked,
Color.WHITE, arrayListOf(BitmapFactory.decodeResource(resources, R.drawable.image_1))))
}
findViewById<View>(R.id.twoPicBtn).setOnClickListener {
findViewById<ImageView>(R.id.testImgV).setImageBitmap(Utils.compoundBitmap(this, true, 300, true, 200, findViewById<CheckBox>(R.id.isArcFg).isChecked,
Color.WHITE, arrayListOf(BitmapFactory.decodeResource(resources, R.drawable.image_1), BitmapFactory.decodeResource(resources, R.drawable.image_2))))
}
findViewById<View>(R.id.threePicBtn).setOnClickListener {
findViewById<ImageView>(R.id.testImgV).setImageBitmap(Utils.compoundBitmap(this, true, 300, true, 200, findViewById<CheckBox>(R.id.isArcFg).isChecked,
Color.WHITE, arrayListOf(BitmapFactory.decodeResource(resources, R.drawable.image_1), BitmapFactory.decodeResource(resources, R.drawable.image_2),
BitmapFactory.decodeResource(resources, R.drawable.image_3))))
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
tools:context=".MainActivity">
<Button
android:id="@+id/onePicBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="一张图"
android:textColor="@color/white"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/twoPicBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="两张图"
android:textColor="@color/white"
android:layout_marginLeft="10dp"
app:layout_constraintLeft_toRightOf="@id/onePicBtn"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/threePicBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="三张图"
android:textColor="@color/white"
android:layout_marginLeft="10dp"
app:layout_constraintLeft_toRightOf="@id/twoPicBtn"
app:layout_constraintTop_toTopOf="parent" />
<CheckBox
android:id="@+id/isArcFg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="圆弧前景,勾选后请重新点击上面👆🏻按钮执行"
android:layout_marginTop="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/onePicBtn"/>
<ImageView
android:id="@+id/testImgV"
android:layout_width="300dp"
android:layout_height="200dp"
android:scaleType="fitXY"
android:src="@drawable/ic_launcher_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.stephen.mytestapplication;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.BitmapDrawable;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.List;
public class Utils {
public static int dp2px(float dp, Context mContext) {
final float scale = mContext.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
//拼装图片
public static Bitmap compoundBitmap(Context context, boolean isWidthDp, int showWidthVal, boolean isHeightDp,
int showHeightVal, boolean isArcFg, int bgColorVal, List<Bitmap> bitmaps) {
int imageWidth = isWidthDp ? dp2px(showWidthVal, context) : showWidthVal;
int imageHeight = isHeightDp ? dp2px(showHeightVal, context) : showHeightVal;
Bitmap compoundBitmap = Bitmap.createBitmap(imageWidth, imageHeight, Bitmap.Config.ARGB_8888);
if(null != bitmaps && bitmaps.size() > 0){
Paint paint = new Paint();
paint.setDither(true);
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.FILL);
Canvas mCanvas = new Canvas(compoundBitmap);
int lineSpacingW;
Path path1, path2, path3;
Matrix matrix1, matrix2;
switch(bitmaps.size()){
case 1:
mCanvas.drawBitmap(resizeBitmap(bitmaps.get(0), imageWidth, imageHeight), 0, 0,null);
break;
case 2:
paint.setColor(bgColorVal);
mCanvas.drawRect(0,0, imageWidth, imageHeight, paint);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
int halfDistanceW = (int)((float)imageWidth/2f);//宽度上分成几份后的单份宽度
int angleSpacingW = dp2px(40f, context);//多余的角宽度
lineSpacingW = dp2px(6f, context);//正常间距的一半
mCanvas.save();
path1 = new Path();
path1.moveTo(0, 0);
path1.lineTo(halfDistanceW + angleSpacingW, 0);
path1.lineTo(halfDistanceW - angleSpacingW - lineSpacingW, imageHeight);
path1.lineTo(0, imageHeight);
path1.close();
mCanvas.clipPath(path1);
//mCanvas.drawPath(path1, paint);
matrix1 = new Matrix();
matrix1.setTranslate(-(halfDistanceW/2f), 0);
mCanvas.drawBitmap(resizeBitmap(bitmaps.get(0), imageWidth, imageHeight), matrix1, null);
mCanvas.restore();
mCanvas.save();
path2 = new Path();
path2.moveTo(imageWidth, 0);
path2.lineTo(imageWidth, imageHeight);
path2.lineTo(halfDistanceW - angleSpacingW, imageHeight);
path2.lineTo(halfDistanceW + angleSpacingW + lineSpacingW, 0);
path2.close();
mCanvas.clipPath(path2);
//mCanvas.drawPath(path2, paint);
matrix2 = new Matrix();
matrix2.setTranslate((halfDistanceW/2f), 0);
mCanvas.drawBitmap(resizeBitmap(bitmaps.get(1), imageWidth, imageHeight), matrix2,null);
mCanvas.restore();
break;
default:
paint.setColor(bgColorVal);
mCanvas.drawRect(0,0, imageWidth, imageHeight, paint);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
int onceDistanceW = (int)((float)imageWidth/5f);//宽度上分成几份后的单份宽度
lineSpacingW = dp2px(5, context);
mCanvas.save();
path1 = new Path();
path1.moveTo(0, 0);
path1.lineTo((2 * onceDistanceW) - lineSpacingW, 0);
path1.lineTo(onceDistanceW - lineSpacingW, imageHeight);
path1.lineTo(0, imageHeight);
path1.close();
mCanvas.clipPath(path1);
//mCanvas.drawPath(path1, paint);
matrix1 = new Matrix();
matrix1.setTranslate(-(2.5f * onceDistanceW), 0);
mCanvas.drawBitmap(resizeBitmap(bitmaps.get(0), imageWidth, imageHeight), matrix1, null);
mCanvas.restore();
mCanvas.save();
path2 = new Path();
path2.moveTo(2 * onceDistanceW, 0);
path2.lineTo((4 * onceDistanceW) + lineSpacingW, 0);
path2.lineTo((3 * onceDistanceW) + lineSpacingW, imageHeight);
path2.lineTo(onceDistanceW, imageHeight);
path2.close();
mCanvas.clipPath(path2);
//mCanvas.drawPath(path2, paint);
mCanvas.drawBitmap(resizeBitmap(bitmaps.get(1), imageWidth, imageHeight), 0, 0,null);
mCanvas.restore();
mCanvas.save();
path3 = new Path();
path3.moveTo(imageWidth, 0);
path3.lineTo(imageWidth, imageHeight);
path3.lineTo((3 * onceDistanceW) + (2 * lineSpacingW), imageHeight);
path3.lineTo((4 * onceDistanceW) + (2 * lineSpacingW), 0);
path3.close();
mCanvas.clipPath(path3);
//mCanvas.drawPath(path3, paint);
matrix2 = new Matrix();
matrix2.setTranslate((2.5f * onceDistanceW), 0);
mCanvas.drawBitmap(resizeBitmap(bitmaps.get(2), imageWidth, imageHeight), matrix2,null);
mCanvas.restore();
break;
}
return isArcFg ? compoundBitmapArcFg(context, false, imageWidth, false, imageHeight, compoundBitmap) : compoundBitmap;
}//end of if
return null;
}
//拼装图片-圆弧前景
public static Bitmap compoundBitmapArcFg(Context context, boolean isWidthDp, int showWidthVal, boolean isHeightDp,
int showHeightVal, Bitmap bitmap) {
int imageWidth = isWidthDp ? dp2px(showWidthVal, context) : showWidthVal;
int imageHeight = isHeightDp ? dp2px(showHeightVal, context) : showHeightVal;
Bitmap compoundBitmap = Bitmap.createBitmap(imageWidth, imageHeight, Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(compoundBitmap);
/*Paint paint = new Paint();
paint.setDither(true);
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.FILL);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);*/
mCanvas.save();
Path pathFg = new Path();
pathFg.addCircle((float)imageWidth/2f, -((float)imageHeight/3f), (float)imageHeight + ((float)imageHeight/5f), Path.Direction.CW);
mCanvas.clipPath(pathFg);
//mCanvas.drawPath(pathFg, paint);
mCanvas.drawBitmap(bitmap, 0, 0,null);
mCanvas.restore();
return compoundBitmap;
}
//压缩图片
public static Bitmap resizeBitmap(Bitmap bitmap, int newWidth, int newHeight) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
float curRatio = Math.max(scaleWidth, scaleHeight);
Matrix matrix = new Matrix();
matrix.postScale(curRatio, curRatio);
return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
}
}
- 附网上参考一个老哥效果比较接近的地址:https://www.jb51.net/article/86090.htm
网友评论