最近群里面有人问,微信群聊的头像是怎么实现的,就花了半个小时写了一个demo,今天又优化了一下,写个博客分享一下。
先上效果图
原理
原理比较简单,就是用画布(canvas)把九张图片合成一张图,然后再按比例缩放一下。
主要就是两个方法,一个是图片合成方法mergePictures(int[] pictures, int row, int column),一个是图片缩放方法resizeImage(Bitmap bitmap, int width, int height)。
优化后可以控制行和列包含几张图片,缩放后图片的宽高。
源码
public class PictureMergeDemo extends AppCompatActivity {
private final static String TAG = "PictureMergeDemo";
private final static int NUM = 3;//每行和列包含几张图片
private Context mContext;
private ImageView mMergePic;
//带合成的图像源
private int[] mPics = {R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_picture_merge_demo);
mContext = this;
mMergePic = (ImageView) findViewById(R.id.iv_merge_pic);
}
@Override
protected void onResume() {
super.onResume();
Bitmap mergePicture = mergePictures(mPics,NUM);
int width = BitmapFactory.decodeResource(mContext.getResources(), mPics[0]).getWidth();
int height = BitmapFactory.decodeResource(mContext.getResources(), mPics[0]).getHeight();
mMergePic.setImageBitmap(resizeImage(mergePicture, width, height));
}
/*
* @pictures the origin images which want to be merged
* @num the row&column num for merge image
* */
public Bitmap mergePictures(int[] pictures, int num) {
if(pictures == null) {
return null;
}
int width = BitmapFactory.decodeResource(mContext.getResources(), pictures[0]).getWidth();
int height = BitmapFactory.decodeResource(mContext.getResources(), pictures[0]).getHeight();
Bitmap mergeBitmap = Bitmap.createBitmap(width * num, height * num ,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mergeBitmap);
for(int i = 0 ; i < num; i++) {
for(int j = 0 ; j < num; j++) {
canvas.drawBitmap(BitmapFactory.decodeResource(mContext.getResources(), pictures[i+j]), width * i, height * j, null );
}
}
canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
return mergeBitmap;
}
/*
* @bitmap the image you want ro resize
* @width the new image's width
* @height the new image's height
* */
public static Bitmap resizeImage(Bitmap bitmap, int width, int height) {
if(bitmap == null || width <= 0 || height <= 0) {
return null;
}
int originWidth = bitmap.getWidth();
int originHeight = bitmap.getHeight();
float scaleWidth = ((float) width) / originWidth;
float scaleHeight = ((float) height) / originHeight;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// if you want to rotate the Bitmap
// matrix.postRotate(45);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, originWidth,
originHeight, matrix, true);
return resizedBitmap;
}
}
布局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="origin picture"/>
<ImageView
android:id="@+id/iv_pic"
android:background="@mipmap/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="merge picture"/>
<ImageView
android:id="@+id/iv_merge_pic"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>