身份证

作者: 魏魏魏魏 | 来源:发表于2016-07-01 19:36 被阅读351次

最近公司一个项目需要实现身份证合成,交给了我两张素材图片,需要合成身份证的正反面图片并保存到本地。

背面素材:

正面素材:

拿到图片后,我的第一反应是将图片作为布局背景,然后在布局里面设置年龄、出生年月等等相关信息。编辑好了,预览一切正常,但是一看加载效果:

预览效果:

可能有的同学会讲,这个只是适配的原因,我在布局里面把间距的单位设为PX,会不会解决这个问题呢?理论上是可以解决问题,但是领导又说了,我们合成图片的时候没有时间开启Activity,怎么办?说好的保存图片怎么办?控件都没有加载,怎么获取控件显示的图片呢?

还好,我还可以用canvas,到时候我直接开一个线程,把合成的图片保存下来就可以了,这样可以完成任务了吧?于是我又换一个思路,继续写代码:

```

public class CanvasView {

private Canvas canvas;private Bitmap bitmap;private Context mContext;/**

* 测试身份证背面画面

* @param v

* @return

*/public Bitmap loadBitmapA (View v)

{

mContext = v.getContext();bitmap = BitmapFactory.decodeResource(v.getResources(), R.drawable.e1);Paint p = new Paint();p.setAntiAlias(true);p.setColor(Color.BLACK);Bitmap bp = Bitmap.createBitmap(485,306, Config.ARGB_8888);Bitmap target = Bitmap.createScaledBitmap(bitmap,485,306, false);String SrcGov ="中国境外管理局";String UserTime ="1998.07.18-2018.07.18";//加入画布,待编辑文字和加入bitmap

canvas = new Canvas(bp);canvas.drawRect(0,0,485,306, p);p.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));canvas.drawBitmap(target,0,0, p);canvas.drawText(SrcGov,200,232, p);canvas.drawText(UserTime,200,272, p);return bp;}/**

* 测试身份证正面画面

* @param v

* @return

*/public Bitmap loadBitmapB (View v)

{

mContext = v.getContext();//正面背景

bitmap = BitmapFactory.decodeResource(v.getResources(), R.drawable.b1);//头像

Bitmap bitmapimage = BitmapFactory.decodeResource(v.getResources(), R.drawable.abm);Bitmap target = Bitmap.createBitmap(485,306, Config.ARGB_8888);Bitmap old = Bitmap.createScaledBitmap(bitmap,485,306, false);Paint p = new Paint();p.setAntiAlias(true);p.setColor(Color.BLACK);p.setTextSize(16);String name ="奥巴马";String gender ="男";String nation ="非汉";String BornYear ="1961";String BornMouth ="08";String BornDate ="04";String Adress ="属国美国华盛顿哥伦比亚特区西北宾夕法尼亚大道1600号";String Adress1 = Adress.substring(0,11);String Adress2 = Adress.substring(11,22);String Adress3 = Adress.substring(22);String BornId ="91188219608043621";//加入画布,待编辑文字和加入bitmap

canvas = new Canvas(target);canvas.drawRect(0,0,485,306, p);p.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));canvas.drawBitmap(old,0,0, p);Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL);p.setTypeface( font );canvas.drawText(name,90,58, p);canvas.drawText(gender,90,96, p);canvas.drawText(nation,195,96, p);canvas.drawText(BornMouth,170,134, p);canvas.drawText(BornDate,215,134, p);canvas.drawText(BornYear,90,134, p);canvas.drawText(Adress1,90,172, p);canvas.drawText(Adress2,90,192, p);canvas.drawText(Adress3,90,212, p);font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);p.setTypeface(font);canvas.drawText(BornId,168,271, p);canvas.drawBitmap(bitmapimage,280,43, null);return target;}

}

```

代码写完了测试一下:

```

public class ViewActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_view);

ImageView image = (ImageView) findViewById(R.id.View);

// image.setImageBitmap(new CanvasView().loadBitmapA(image));

image.setImageBitmap(new CanvasView().loadBitmapB(image));

}

}

```

反面

正面

刚刚测试完,领导又来了,看了测试结果后说我们现在做的都是头像尺寸固定的,但是在项目实际应用当中,身份证头像的照片尺寸是不确定的,且图片是彩色的,需要将头像的色彩改为黑白色,这几点需要在项目里实现。好吧,领导的想法最重要,有了想法才有看法。为了没有不好的看法,我继续写呗!

```

/**

* 修改图片尺寸

* @param bitmap

* @return

*/

private static Bitmap changeBitmapSize(Bitmap bitmap)

{

int w = bitmap.getWidth();

int h = bitmap.getHeight();

//原图尺寸为102*126,现放大为148*182

//所以长和宽比例分别为1.45  1.44

float radioW = 148.0f/w;

float radioH = 182.0f/h;

Matrix matrix = new Matrix();

matrix.postScale(radioW,radioH);  //长和宽放大缩小的比例

return Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);

}

```

因为头像尺寸是固定的,而且一般图片差异不会特别大,所以这里就没有使用宽高比,而是暴力地修改了。后面的彩色图片改为黑白图片,我也去给它简单过滤一下就好!

```

/**

* 图片换色,由黑白图片更换为彩色图片

* @param bmpOriginal

* @return

*/

public static Bitmap toGrayscale(Bitmap bmpOriginal)

{

int width, height;

height = bmpOriginal.getHeight();

width = bmpOriginal.getWidth();

Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

Canvas c = new Canvas(bmpGrayscale);

Paint paint = new Paint();

ColorMatrix cm = new ColorMatrix();

cm.setSaturation(0);

ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);

paint.setColorFilter(f);

c.drawBitmap(bmpOriginal, 0, 0, paint);

return bmpGrayscale;

}

```

这下总算搞定了,准备下班了,领导又来了,说是图片的背景颜色有白色、黑色、蓝色,这些颜色必须改成透明色。且头像图片的内容不能变。这个就玩大了,,,我继续上网求助度娘(实际上这一点花了身为小菜的我两天时间)。但是度娘也不是万能的,提供了好多办法都是行不通的,最后,快下班的时候终于搞定了!

```

/**

* 修改背景颜色

* @param bitmap 需要修改的图片

* @param replaceThisColor 修改前的颜色

* @return

*/

public Bitmap createTransparentBitmapFromBitmap(Bitmap bitmap,

int replaceThisColor) {

if (bitmap != null) {

int picw = bitmap.getWidth();

int pich = bitmap.getHeight();

int[] pix = new int[picw * pich];

bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);

for (int y = 0; y < pich; y++)

{

for (int x = 0; x < picw; x++)

{

int index = y * picw + x;

if (pix[index] == replaceThisColor)

{

pix[index] = Color.TRANSPARENT;

}

}

}

Bitmap bm = Bitmap.createBitmap(pix, picw, pich,

Bitmap.Config.ARGB_8888);

return bm;

}

return null;

}

```

最后将工具类提供一个静态方法供其它使用类调用:

```

package com.hhqy.vicent;

import java.io.File;

import java.io.FileOutputStream;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Bitmap.Config;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.ColorMatrix;

import android.graphics.ColorMatrixColorFilter;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.PorterDuff.Mode;

import android.graphics.PorterDuffXfermode;

import android.graphics.Typeface;

import android.os.Environment;

import android.widget.Toast;

public class CanvasView {

private static Canvas canvas;

private static Context mContext;

/**

* 仅供测试使用

*/

public static String path;

/**

* 获取合成图片

* @param info 图片文本信息

* @param type 图片类型 1代表正面, 2代表反面

* @param bitmap 合成反面的头像图片

* @param context 获取背景资源用

* @param baseColor 当前图片的背景颜色,透明的话设置为111111111

* 注意:证件地址长度不得超过33个字节

*/

public static void getPicture(String[] info,int type,Bitmap bitmap,Context context,int baseColor){

mContext = context;

if(1==type)

{

saveMyBitmap(loadBitmapA(info), "First_"+System.currentTimeMillis());

return;

}

else

{

saveMyBitmap(loadBitmapB(info,bitmap,baseColor), "Second_"+System.currentTimeMillis());

return ;

}

}

/**

* 将bitmap保存为指定名称图片

* @param mBitmap

* @param bitName

*/

public static void saveMyBitmap(Bitmap mBitmap,String bitName)

{

if(Environment.getExternalStorageState()!=Environment.MEDIA_MOUNTED)

{

File dir=new File(Environment.getExternalStorageDirectory() + "/TestPicture");

if(!dir.exists())dir.mkdirs();

File f = new File(dir, "/"+bitName);

path= f.getAbsolutePath();

try {

FileOutputStream fOut = new FileOutputStream(f);

mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);

fOut.flush();

fOut.close();

Toast.makeText(mContext, bitName+"保存成功", Toast.LENGTH_LONG).show();

} catch (Exception e) {

e.printStackTrace();

}

}

}

/**

* 测试身份证背面画面

* @param v

* @return

*/

public static Bitmap loadBitmapA (String[] info)

{

Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.e1);

Paint p = new Paint();

p.setAntiAlias(true);

p.setColor(Color.BLACK);

Bitmap bp = Bitmap.createBitmap(485, 306, Config.ARGB_8888);

Bitmap target = Bitmap.createScaledBitmap(bitmap, 485, 306, false);

String SrcGov = info[0];

String UserTime = info[1];

//加入画布,待编辑文字和加入bitmap

canvas = new Canvas(bp);

canvas.drawRect(0, 0, 485, 306, p);

p.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

canvas.drawBitmap(target, 0, 0, p);

canvas.drawText(SrcGov, 200, 232, p);

canvas.drawText(UserTime, 200, 272, p);

return bp;

}

/**

* 测试身份证正面画面

* @param v

* @return

*/

public static Bitmap loadBitmapB (String[] info,Bitmap bmp,int needReplaseColor)

{

//正面背景

Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.b1);

//头像

//彩色变黑白色

bmp = toGrayscale(bmp);

// 修改背景颜色

if(needReplaseColor!=111111111)

bmp = createTransparentBitmapFromBitmap(bmp, needReplaseColor);

//放大图片

bmp = changeBitmapSize(bmp);

Bitmap target = Bitmap.createBitmap(485, 306, Config.ARGB_8888);

Bitmap old = Bitmap.createScaledBitmap(bitmap, 485, 306, false);

Paint p = new Paint();

p.setAntiAlias(true);

p.setColor(Color.BLACK);

p.setTextSize(16);

String name = info[0];

String gender = info[1];

String nation = info[2];

String date = info[3];

int end = date.lastIndexOf(".");

int start = date.indexOf(".");

String BornYear = date.substring(0,start);

String BornMouth = date.substring(start+1, end);

String BornDate = date.substring(end+1);

String Adress = info[4];

String Adress1 = null;

String Adress2 = null;

String Adress3 = null;

if(Adress.length()>=11)

{

Adress1 = Adress.substring(0, 11);

if(Adress.length()>=22)

{

Adress2 = Adress.substring(11,22);

if(Adress.length()>=22)

{

Adress3 = Adress.substring(22);

}

}

else

{

Adress2 = Adress.substring(11,Adress.length());

}

}

else

{

Adress1 = Adress.substring(0, Adress.length());

}

String BornId = info[5];

//加入画布,待编辑文字和加入bitmap

canvas = new Canvas(target);

canvas.drawRect(0, 0, 485, 306, p);

p.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

canvas.drawBitmap(old, 0, 0, p);

Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL);

p.setTypeface( font );

canvas.drawText(name, 90, 58, p);

font = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL);

p.setTypeface(font);

canvas.drawText(gender, 90, 96, p);

canvas.drawText(nation, 195, 96, p);

canvas.drawText(BornMouth, 170, 134, p);

canvas.drawText(BornDate, 215, 134, p);

canvas.drawText(BornYear, 90, 134, p);

canvas.drawText(Adress1, 90, 172, p);

if(Adress2!=null)

{

canvas.drawText(Adress2, 90, 192, p);

if(Adress3!=null)

{

canvas.drawText(Adress3, 90, 212, p);

}

}

font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);

p.setTypeface(font);

canvas.drawText(BornId, 168, 271, p);

canvas.drawBitmap(bmp, 280, 43, null);

return target;

}

/**

* 修改图片尺寸

* @param bitmap

* @return

*/

private static Bitmap changeBitmapSize(Bitmap bitmap)

{

int w = bitmap.getWidth();

int h = bitmap.getHeight();

//原图尺寸为102*126,现放大为148*182

//所以长和宽比例分别为1.45  1.44

float radioW = 148.0f/w;

float radioH = 182.0f/h;

Matrix matrix = new Matrix();

matrix.postScale(radioW,radioH);  //长和宽放大缩小的比例

return Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);

}

/**

* 图片换色,由彩色图片更换为黑白颜色

* @param bmpOriginal

* @return

* 注意:经测试,透明图片经此设置的话会讲背景色更改为黑色

*/

public static Bitmap toGrayscale(Bitmap bmpOriginal)

{

int width, height;

height = bmpOriginal.getHeight();

width = bmpOriginal.getWidth();

Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

Canvas c = new Canvas(bmpGrayscale);

Paint paint = new Paint();

ColorMatrix cm = new ColorMatrix();

cm.setSaturation(0);

ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);

paint.setColorFilter(f);

c.drawBitmap(bmpOriginal, 0, 0, paint);

return bmpGrayscale;

}

/**

* 修改背景颜色

* @param bitmap 需要修改的图片

* @param replaceThisColor 修改前的颜色

* @return

*/

public static Bitmap createTransparentBitmapFromBitmap(Bitmap bitmap,

int replaceThisColor) {

if (bitmap != null) {

int picw = bitmap.getWidth();

int pich = bitmap.getHeight();

int[] pix = new int[picw * pich];

bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);

for (int y = 0; y < pich; y++)

{

for (int x = 0; x < picw; x++)

{

int index = y * picw + x;

if (pix[index] == replaceThisColor)

{

pix[index] = Color.TRANSPARENT;

}

}

}

Bitmap bm = Bitmap.createBitmap(pix, picw, pich,

Bitmap.Config.ARGB_8888);

return bm;

}

return null;

}

}

```

调用方法:

```

//正面测试

// String[] info = {"嵊州市公安局","2000.01.01-2020.01.01"};

// CanvasView.getPicture(info, 1, null, this, 0);

//背面测试

String[] info = {"马云","男","汉","1964.09.10","杭州市西湖区西溪新座5幢706室","330683196309100310"};

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.jack);

CanvasView.getPicture(info, 2, bmp, this, Color.WHITE);

image.setImageBitmap(BitmapFactory.decodeFile(CanvasView.path));

```

最后的测试效果:

正面(反正我是这么定义的)

反面

小菜作品,恳请各位大神斧正!!!!周末愉快,找(动词,寻找的意思。)女朋友去了!

大伙看完了不要忘记点评哦,比较奥巴马的平头太平了!!!

相关文章

  • 身份证ocr识别核验webservice API接口调用

    关键词:身份证识别 身份证ocr识别 身份证核验 身份证识别核验 身份证ocr核验API 现在出门没有身份证可谓是...

  • 身份证拍照识别sdk

    身份证拍照识别SDK,身份证拍照识别,android身份证拍照识别,身份证拍照识别 一、身份证拍照识别sdk应用背...

  • Android 好用的身份证拍照界面封装

    手持身份证调用 身份证正面调用 身份证反面调用 CameraActivity.KEY_OUTPUT_FILE_PA...

  • golang 身份证号码处理

    身份证格式验证 身份证获取年龄信息

  • 合伙人合同

    A姓名_______,身份证_______,电话_______住址_______ B姓名_______,身份证__...

  • 微信小程序身份证ocr识别

    关键词:身份证识别 身份证ocr识别 微信小程序身份证识别 微信小程序ocr识别 身份证ocr识别api (网图,...

  • 离婚协议

    男方: ,身份证: ,现常住地址: 女方: ,身份证: ...

  • 生命艺术合伙人草案

    股东协议书 甲方: ,身份证号: 乙方: ,身份证号: 丙方: ,身份证号: 丁方: ...

  • 指导教案记录

    1.ppT第二张放映文字有问题。 2.完整呈现身份证。 3.认一认身份证;读一读身份证;找一找,写一写身份证;介绍身份证

  • 今日份get的小知识点

    身份证原来包括一代身份证和二代身份证! 今天看书的时候突然读到一句话“如果没有二代身份证可以用一代身份证进行办理…...

网友评论

      本文标题:身份证

      本文链接:https://www.haomeiwen.com/subject/wrxqjttx.html