由于项目需要展示头像跟微信群组那样的组合,网上搜了一堆都不太符合要求,额,可能没有找到吧
下面就分享一个自己整合的头像合成工具类:
先说一下实现思路和步骤:
(1)首先要创建一张空白的大图片
(2)根据需要的图片宽度(此处都是正方形),计算所有图片在空白图片中的坐标,由于要设置小图片直接的间隙,此处就要加上间隙的宽度
(3)以此需要合成的图片与空白图片进行组合(第二次组合要在第一次组合的基础上进行)
(4)组合成之后对图片设置背景颜色(及边框和间隙的颜色)
此图片组合可支持1-9张图片的组合展示
以下就是具体的实现类和参考实例代码中有详细注释:
/**
* 实现9张图片组合
* <p>
* Created by:wangjian on 2017/11/17 10:28
*/
public class NineImageCombine {
/**
* 进行图片组合
*
* @param bitmaps 图片列表
* @param parentWidth 图片显示的宽度
* @param padding 图片间距大小
* @param borderColor 边框和间隙颜色
* @return
*/
public static Bitmap combineImages(List<Bitmap> bitmaps, int parentWidth, int padding, int borderColor) {
int size = bitmaps.size();
// 根据图片数计算列数
int maxColumn = getMaxColumn(size);
// 计算图片行数
// int maxRow = getMaxRow(size);
// 图片实际占用宽度(去除padding)
int valiableImageWidth = parentWidth - (maxColumn - 1) * padding;
// 根据列数计算图片宽度和高度
int imgWidth = valiableImageWidth / maxColumn;
// int imgHeight = valiableImageWidth / maxColumn;
// padding占据图片宽度的百分比
float paddingPer = (float) padding / imgWidth;
// 画布,空白大图
Bitmap newBitmap = Bitmap.createBitmap(parentWidth, parentWidth, Bitmap.Config.ARGB_8888);
// 获得各图片坐标
List<PointF> points = getPointFlist(size, maxColumn, imgWidth, paddingPer);
for (int i = 0; i < points.size(); i++) {
// 生成指定大小的缩略图
Bitmap thumBitmap = getThumbnailBitmap(bitmaps.get(i), imgWidth);
// 组合成新的图片
newBitmap = mixtureBitmap(newBitmap, thumBitmap, points.get(i));
}
if (borderColor != 0) {
newBitmap = setBgAndBorder(newBitmap, borderColor, padding);
}
return newBitmap;
}
/**
* 计算每一张图片的坐标点
*
* @param size 图片的数量
* @param maxColumn 行数
* @param imgWidth 每一张图片的宽度
* @param paddingPer 图片中间的缝隙与图片宽度的百分比
* @return
*/
private static List<PointF> getPointFlist(int size, int maxColumn, float imgWidth, float paddingPer) {
List<PointF> pointFList = new ArrayList<>();
// 1张图片
if (maxColumn == 1) {
int xleft = 0;
int xtop = 0;
addPointF(pointFList, imgWidth, xleft, xtop);
}
// 2,3,4张图片
else if (maxColumn == 2) {
if (size == 2) {
// 对应坐标 w == imgWidth
// 0,w/2 w w/2
for (int i = 0; i < size; i++) {
//计算左上角坐标
float xleft = 0;
float xtop = 0;
switch (i) {
case 0:
xleft = 0;
xtop = 1 / 2f;
break;
case 1:
xleft = 1 + paddingPer;
xtop = 1 / 2f;
break;
}
addPointF(pointFList, imgWidth, xleft, xtop);
}
}
else if (size == 3) {
// 对应坐标 w == imgWidth
// w/2,0
// 0,w w w
for (int i = 0; i < size; i++) {
//计算左上角坐标
float xleft = 0;
float xtop = 0;
switch (i) {
case 0:
xleft = 1 / 2f;
xtop = 0;
break;
case 1:
xleft = 0;
xtop = 1 + paddingPer;
break;
case 2:
xleft = 1 + paddingPer;
xtop = 1 + paddingPer;
break;
}
addPointF(pointFList, imgWidth, xleft, xtop);
}
}