做了一个需求,后台接口返回给前端的不是一张完整的图形验证码而是4行5列的base64的数组,接口内容如下
{
"status": "2000",
"message": "success",
"data": [
[{
"x": 0,
"y": 0,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAfUlEQVR42mP4jws8OQLBhAAOdQz/\naQRoYvC/f/9oY/C5HWeob/D3z9/+17tW4zGY2MhDA6tbV/wvNs7DYTDMUGIMR1J3Z8f6/6Wm+TgM\nRjeMkOFQ+c9vP/1v9q4HG9rq24BmMC5D8BkOFP9ybd//GscKsKHV9uX/L+w+/x8Ao/z21VGxpJMA\nAAAASUVORK5CYII="
}, {
"x": 0,
"y": 9,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAA70lEQVR42mP4DwJPjiAwMh8ZoKuB\ngm839/+fndr2v9g473+pWcH/60ev/p+TP/M/w39cAJvhaODpzSf/m93LwYaCcHdg7f/52Z3/S03z\n8RhMBNg8YQPcUHTMkGA75T8Io3gVF0YDiyvngw0ptygEB0OdcyWYX+9ShXAxzAK4RUQEy4bedf9X\nVUz4/+jApv+vHr78v3XKZrDBy+uX4A4KvBZhsfTKwcv/yy2LwS4/vPwAgTBGcilOi4Dyv+8f/N/o\nConEEmDEfbqyh/xUgRw3n6/uhUfaxPhesDxFqQIG/v399//YmiP/t0/bCk6CIAAALx+oXLNtiTQA\nAAAASUVORK5CYII="
}, {
"x": 0,
"y": 18,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAPklEQVR42mP4TyPAMIwMfnIEgqlq\nMMxQYgxHVwvFDARdSshwHPIMRHkfn+F4DUb3NjbFuIKGKBeTE3k4whgAuTYG+mHrzJgAAAAASUVO\nRK5CYII="
}, {
"x": 0,
"y": 27,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAMklEQVR42mP4Tyl4cgSC0QADhgJ8\nmCyDyXAVZQbjM5RsgwkZiicIGSgylOIwJgMMPYMBr/0KAGH6ORoAAAAASUVORK5CYII="
}],
[{
"x": 22,
"y": 0,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAdElEQVR42mP4DwNPjkAwNoBLDiaO\nRY7hP40Aw9KaRf/P7zxLfYOLjfP+V9uX/5+ROeX/zRM3qGswDM/Mmkobg6emTsSvGl8E4zP41tZ1\n1DO41rECbOj2jhmYmpCTEzEY2eByy+L/LT4N/3/fP4TfNSS4FgQAhjvm7OUB4RgAAAAASUVORK5C\nYII="
}, {
"x": 22,
"y": 9,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAyUlEQVR42mMoNs77v3nixv+fr+z5\n//fR4f9YwZMjhDGaegaQwTDc5Fb+/92zt7gNxWcpGkAxGITPbD1NmktxGbxr9o7/e+ft+j83o/3/\novzu/3///CXaVXhdTJJmUlxMiavwu5iAzcianz758L+388B/F7vp/030+v7HhC/9P6lp+f+3l/eT\n52JQMpzVufK/ueGE/8a6fSg4zGf6/3dXD+AxGAf49+///6qyrXCDnGyn/S8t3PQ/I3n1f0ebaf9v\nXH+JoefF87f/AaWBxmSRZ+2DAAAAAElFTkSuQmCC"
}, {
"x": 22,
"y": 18,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAABKklEQVR42mP4TwDMnHbsv7FuHxj3\n9xz8/+PHb7zqP338+r+mZOZ/BnyKLpx7+t9Uvx9s6LIl5/4TA+ZM2/g/J7kHv8GJsSvAhtZWbifK\n0BfP34INzU/rw23w2TNP4EHQ2br3f7Dfgv8WhhP+xwTN/L9963Wseu7efgI2eGrfGqDBT478R8FQ\n0NOxH24wyOV7d9/+P70d4gNQ8Ny4/hKr4Tu3nvjfUjsfycVoBkeHLQEbkh4z5/+fh4fBcjuWbIJb\ntnXRhv+4HAUCWA3++/fffyuTSWADDh+8B5fPip8LN/junTd4wxurwe/efYMbcPH8U7D40Q1b4WKp\nUbPxuhbExxrGXz7//G+iBzFk3Zx1/89u3/7f0RLiA1vzyf8fPXz/H1cQgsC/f///AwA/m6Zt46R7\nNwAAAABJRU5ErkJggg=="
}, {
"x": 22,
"y": 27,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAbElEQVR42mP4DwNPjkAwFIQGLPxv\nrNuHgk31+/7vW7UZoRYZI4Hv337+Z8Bl8NUrL/4X5mz472A19b+N6YT/DhYT/2/ddO0/BsBi8McP\nX3AbjFUzPowGSDOYBDkGQjaTbzAlLiYqKKgMhp7BADi+8PweUYAWAAAAAElFTkSuQmCC"
}],
[{
"x": 44,
"y": 0,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAWUlEQVR42mP4/+TIfzAGAWQ2DGAT\nIwIw/KcRGDUYzWBcEUhmxNHYYGwGYcNQcK7LFIxJMxiHi+u/XIJjGDjbafZ/U43L/5kFAf9nTlr0\nf0rPvP/HDp6GywMA5Bv9LwPA5b4AAAAASUVORK5CYII="
}, {
"x": 44,
"y": 9,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAABUElEQVR42pXS3UoCURQFYF+q5+im\nQIxgKsnCcvIPCpUiksqstNCEIMXC9EKjKKEILBgsGFRQMBTEKKFMijDzcla6wdEJMVuwb9ac87EP\njAwlDn1PI6YiB9bvxThjBDPMQm13Yl87CI1CBWZIA/4uRWdlnZf6idXsIIBVmlHIP1K3WEtDGzqk\nfmNajqRt4Bf8x7bNfLx/wqRbRZLPiJ0gCLAtuwg+C19S1x3uTB8vCgfOCVUz8/iq1nrAPTbuTDqV\nhXvLS+jUqBHZTE789u+Nyy8VWPRrmFToCWzNSTAquSbCpec3BFx+WHQ7mFVu4uIo2HXjg71jCdga\n1YgB9e96G67mYvA5fA3MjpkJ6URP4xK4/FqBUq4laKzxq9lX3FhgrSJ+zyXasNngIWROtQ2PM4JI\nKEYbN7ub64TkebErjoD1pV08FUvUxW95Ec4/FMSzP9o/kivKS9FCAAAAAElFTkSuQmCC"
}, {
"x": 44,
"y": 18,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAABQUlEQVR42q2S30vCUBTH7x9ZvQX9\npB7KRBCiJpksSJqhLMok3CgJSUETKXoSUSiix54CQ1gPUWZuEe2H85u7i7FFIf34wIHLOfd+7rmH\nS+YmOayv7uPhvg2L0JYAKxeNHEDXDbjRNB2K/OLJrTFxjA354J9mYJqmkycbbAa6ZgsU5RW+mRiW\nAjt4askYRC5TolIrLmpXnhppPXbsblQdu3wB81MxsLnsQGnx6NSRWuvPEMPo4vKkiFCApyMoCofg\nqsd29a5OQ31TnQNyR8H2pkCFEyN+nJUrX15MWCYNMSFCjIsIL+5BbVSpjMo/xI2bJsRklgpnR4MY\nH15ANMyjeSt9+yJiHexJdUSW0zgvFRyZW0zjh1DxdaWMUDCFbn8sbpEj/wWkJ9XArSRRyee9Hf6l\n6/5ekmBT/Z/A4bmt4D95B9IgxMBQ/O73AAAAAElFTkSuQmCC"
}, {
"x": 44,
"y": 27,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAQUlEQVR42mPITen531Ez/T8YPDmC\nG5MIGHKSe/4vm7oI1WBkQK7BP+4e/P/19gHquxhFIzVdjNXgwe1iGoGhZzAAmoUBZGfjkcgAAAAA\nSUVORK5CYII="
}],
[{
"x": 66,
"y": 0,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAA20lEQVR42mP4jw6eHIFgQoCAOob/\nNAIEDf7x6/f/P3/+Usfgf//+/d9w5Nx/38oJ/1Wjyv+rAHFw7ZT/J6/dJd/gRy/f/g+pm/pfObIM\nA2vEVv6/9uAZ6QaDXOpW0Aw3yDa37f+FO4/+P371FkxbZDb/z5+0lAwXA2N50+aVYK8nNvT8//r9\nJ1zq09fv/41S6v9n9y9GTRU4MAO25HPl3pP/fx4dRklO5TNWgX2xaOdRnMnt+Mmb/wtK5/33D+uA\nGowrTULFl+4+DjY0vm02znQ8d+He/16BrXAMACDdzhrX/3TOAAAAAElFTkSuQmCC"
}, {
"x": 66,
"y": 9,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAABkElEQVR42n2S7StDcRTH7/9CIsUr\n/4SHF4wXs0Ye8vBCq6tsy1iIFl4oTW1FnmZyRSElNWMeXihGsZqMMhrD0tZmj1+7x1z3tnHq2+/X\nOb/z+XZOPwbeQ5D4EN8zwa0voUChRq3GgFDk87cgesutnaC8epgkqx9D36AVzNlomQT005BKpTC/\nc4Tixl7U6Y0IhiM53zltm6ioGSEoy07i7cqGd9ceGH3oEjxcLB46s+1AoVKLKu0EHv0BZEUaGr07\nQFOHkaBq3QKi0TiVHryvYISRMgq4bahpa0WevIdO7fMpePNcYIt5kaAtnVMIBn8nchy7wMTiCZg2\n7NCYOCiGTCht7icoryKlBiqVXJiEN/gxCd/uQyY3EPj8wiPxnLPYwXj97wLoL914fdQgXtfOyipB\nu7qns4Zh1bNgEokkSpr6/gW7H3xZzZ0NLIG3rCuSVT45dynPkIPRKgHl16uFUzlszoJGIjFUyr6/\n14v/Q1LTDVjR3mX6BueKZPpn/BWe+2eC1irGJXnH0TXll7lDfAGjQ2/0tFbQvAAAAABJRU5ErkJg\ngg=="
}, {
"x": 66,
"y": 18,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAApElEQVR42mP4Twa4fPXhf6/A1v/R\niRP+f/z4FSx2686z/6HRPf8z82b9//nz938Gcgy+c/c52OCEtCn/G9tW/W/rWvvfL6T9f3zq5P9P\nn70DqyHLYBCYNH3bf/+wDjBOzJj6fzKQ//7DF7g8psFPjkAwEeDv33845RiwGkqM4ehq0TADTpcS\nMpyAPANeRfg0EzQYWQGQznsVi9vLJLuYnMgjEMYAJlDrQZ/QXoYAAAAASUVORK5CYII="
}, {
"x": 66,
"y": 27,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAANElEQVR42mP4Ty54cgSCcQAGuAJ8\nmCyDyXUV2QYT0EiewYQMRVaDAzOQZSjFYUwBGHoGAwBlKAlU8Ri0CwAAAABJRU5ErkJggg=="
}],
[{
"x": 88,
"y": 0,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAARUlEQVR42mP4/+TIfzDGBnDJwcTx\nyDH8pxEYNZhEg/FFMA71DERpIsfgosLJ/x+f3YU7ORGDsSU3r8DW/6UlU6jqWhAGANboA922paYt\nAAAAAElFTkSuQmCC"
}, {
"x": 88,
"y": 9,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAXklEQVR42mPwCmz9n5LW9x8reHKE\nMMahniEqrvt/TdU0/IbisxSHOIN3UNv/DUtWkO5SQgaDguLTzf2kuYoYF+flTySsmRwXb1q6knRX\nEePiW8e308ZgSjTjN5hGAACBYe14UZsGqgAAAABJRU5ErkJggg=="
}, {
"x": 88,
"y": 18,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAR0lEQVR42mP4TyPAQDODZ+1o/I+O\naeZibJaR5IAnR4AGAwkwxgdwqMFpIU6DYWLEYix6CbuYGB+RbDCZrsVvMC7NhHwCFQcAa5jrc7sd\nN6kAAAAASUVORK5CYII="
}, {
"x": 88,
"y": 27,
"img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAJCAYAAAA2NNx1AAAAL0lEQVR42mP4/+TIfzBGBjAxYjA6\ngIoz4FSAbAEpciQZPPRcTDeDiQoKGoGhZzAAxEcAmH7LnCgAAAAASUVORK5CYII="
}]
]
}
尝试了几种方法,记录一下,也给没做过类似需求的人一个参考
将上述代码以json文件保存,放到项目assert目录下
读取json文件并解析数据
private void getDataFromJson() {
StringBuilder newstringBuilder = new StringBuilder();
InputStream inputStream = null;
try {
inputStream = getResources().getAssets().open("bitmap.json");
InputStreamReader isr = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(isr);
String jsonLine;
while ((jsonLine = reader.readLine()) != null) {
newstringBuilder.append(jsonLine);
}
reader.close();
isr.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
String result = newstringBuilder.toString();
Gson gson = new Gson();
ImageCodeEntity codeEntity = gson.fromJson(result, ImageCodeEntity.class);
imageCode = codeEntity.getData();
}
然后根据imagecode数据拼接图片,方法一就是死办法,一个一个拼
private void setData() {
List imageCodeEntitie0 = imageCode.get(0);
List imageCodeEntitie1 = imageCode.get(1);
List imageCodeEntitie2 = imageCode.get(2);
List imageCodeEntitie3 = imageCode.get(3);
List imageCodeEntitie4 = imageCode.get(4);
Bitmap viewColume0 = PjbTextUtils.fromUpToDown(PjbTextUtils.stringToBitmap(imageCodeEntitie0.get(0).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie0.get(1).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie0.get(2).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie0.get(3).getImg()));
Bitmap viewColume1 = PjbTextUtils.fromUpToDown(PjbTextUtils.stringToBitmap(imageCodeEntitie1.get(0).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie1.get(1).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie1.get(2).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie1.get(3).getImg()));
Bitmap viewColume2 = PjbTextUtils.fromUpToDown(PjbTextUtils.stringToBitmap(imageCodeEntitie2.get(0).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie2.get(1).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie2.get(2).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie2.get(3).getImg()));
Bitmap viewColume3 = PjbTextUtils.fromUpToDown(PjbTextUtils.stringToBitmap(imageCodeEntitie3.get(0).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie3.get(1).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie3.get(2).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie3.get(3).getImg()));
Bitmap viewColume4 = PjbTextUtils.fromUpToDown(PjbTextUtils.stringToBitmap(imageCodeEntitie4.get(0).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie4.get(1).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie4.get(2).getImg())
, PjbTextUtils.stringToBitmap(imageCodeEntitie4.get(3).getImg()));
bitmapFinal = PjbTextUtils.fromLeftToRight(viewColume0, viewColume1, viewColume2, viewColume3, viewColume4);
ivImagecode1.setImageBitmap(bitmapFinal);
}
这样明显代码量太多,而且繁杂,改进成方法二,代码如下
private void setData2() {
List bitmapColume = new ArrayList<>();
List bitmapRow = new ArrayList<>();
for (int r = 0; r < imageCode.size(); r++) {
List imageCodeEntitie = imageCode.get(r);
for (int c = 0; c < imageCodeEntitie.size(); c++) {
bitmapColume.add(c, PjbTextUtils.stringToBitmap2(imageCodeEntitie.get(c).getImg()));
}
bitmapRow.add(PjbTextUtils.fromUpToDown(bitmapColume.get(0), bitmapColume.get(1), bitmapColume.get(2), bitmapColume.get(3)));
}
bitmapFinal = PjbTextUtils.fromLeftToRight(bitmapRow.get(0), bitmapRow.get(1), bitmapRow.get(2), bitmapRow.get(3), bitmapRow.get(4));
ivImagecode.setImageBitmap(bitmapFinal);
}
但是思考后感觉还是不够灵活,如果后台改了数据格式就会报错,因此诞生方法三
private Bitmap getBitmap(List> data) {
Bitmap result = Bitmap.createBitmap(200, 100, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
int width = 0;
int height = 0;
for (List datum : data) {
for (DataBean dataBean : datum) {
Bitmap b = PjbTextUtils.stringToBitmap(dataBean.getImg());
width = Math.max(dataBean.getX() + b.getWidth(), width);
height = Math.max(dataBean.getY() + b.getHeight(), height);
canvas.save();
canvas.clipRect(0, 0, width, height);
canvas.drawBitmap(b, dataBean.getX(), dataBean.getY(), null);
canvas.restore();
}
}
result = Bitmap.createBitmap(result, 0, 0, width, height);
return result;
}
上面用到的工具类方法如下
/**
* 从上往下拼接图片
*
* @param bit1
* @param bit2
* @param bit3
* @param bit4
* @return
*/
public static Bitmap fromUpToDown(Bitmap bit1, Bitmap bit2, Bitmap bit3, Bitmap bit4) {
int width = bit1.getWidth();
int height = bit1.getHeight() + bit2.getHeight() + bit3.getHeight() + bit4.getHeight();
//创建一个空的Bitmap(内存区域),宽度等于第一张图片的宽度,高度等于两张图片高度总和
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
//将bitmap放置到绘制区域,并将要拼接的图片绘制到指定内存区域
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bit1, 0, 0, null);
canvas.drawBitmap(bit2, 0, bit1.getHeight(), null);
canvas.drawBitmap(bit3, 0, bit1.getHeight() + bit2.getHeight(), null);
canvas.drawBitmap(bit4, 0, bit1.getHeight() + bit2.getHeight() + bit3.getHeight(), null);
return bitmap;
}
public static Bitmap fromUpToDown2(Bitmap bit1, Bitmap bit2) {
int width = bit1.getWidth();
int height = bit1.getHeight() + bit2.getHeight();
//创建一个空的Bitmap(内存区域),宽度等于第一张图片的宽度,高度等于两张图片高度总和
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
//将bitmap放置到绘制区域,并将要拼接的图片绘制到指定内存区域
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bit1, 0, 0, null);
canvas.drawBitmap(bit2, 0, bit1.getHeight(), null);
return bitmap;
}
/**
* 从左往右拼接图片
*
* @param bit1
* @param bit2
* @param bit3
* @param bit4
* @param bit5
* @return
*/
public static Bitmap fromLeftToRight(Bitmap bit1, Bitmap bit2, Bitmap bit3, Bitmap bit4, Bitmap bit5) {
int width = bit1.getWidth() + bit2.getWidth() + bit3.getWidth() + bit4.getWidth();
int height = bit1.getHeight();
//创建一个空的Bitmap(内存区域),宽度等于第一张图片的宽度,高度等于两张图片高度总和
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
//将bitmap放置到绘制区域,并将要拼接的图片绘制到指定内存区域
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bit1, 0, 0, null);
canvas.drawBitmap(bit2, bit1.getWidth(), 0, null);
canvas.drawBitmap(bit3, bit1.getWidth() + bit2.getWidth(), 0, null);
canvas.drawBitmap(bit4, bit1.getWidth() + bit2.getWidth() + bit3.getWidth(), 0, null);
canvas.drawBitmap(bit5, bit1.getWidth() + bit2.getWidth() + bit3.getWidth() + bit5.getWidth(), 0, null);
return bitmap;
}
/**
* base64转bitmap
*
* @param string
* @return
*/
public static Bitmap stringToBitmap(String string) {
Bitmap bitmap = null;
try {
byte[] bitmapArray = Base64.decode(string.split(",")[1], Base64.DEFAULT);
bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
/**
* base64转bitmap
*
* @param string
* @return
*/
public static Bitmap stringToBitmap2(String string) {
Bitmap bitmap = null;
try {
byte[] bitmapArray = Base64.decode(string.replace("data:image/png;base64,", ""), Base64.DEFAULT);
bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
最终效果图如下