其他分享
首页 > 其他分享> > 利用vCard实现扫码将个人信息保存到通讯录

利用vCard实现扫码将个人信息保存到通讯录

作者:互联网

利用vCard实现扫码将个人信息保存到通讯录

一、功能

利用vCard实现扫码将个人信息保存到通讯录

二、vCard

1.简单了解

vCard是电子名片的文件格式标准。它一般附加在电子邮件之后,但也可以用于其它场合(如在互联网上相互交换)。vCard可包含的信息有:姓名、地址资讯、电话号码、URL,logo,相片等。

2.通讯录vcard关键字描述

字段名字段类型字段值备注
FN无定义该字段值定义了一种格式化名字(Formatted Name),日常名字的表示方法。基于X.520的普通名字语义规则
N无定义字段值表示人名或物名形式:[Family Name];[Given Name];[Additional Names];
[Name Prefix];[Name Suffix]
有些字段值可能只有一个“;”
PHOTOGIF,CGM,WMF,BMP,MET,PMB,
DIB,PICT,TIFF,PS,PDF,JPEG,
MPEG,MPEG2,AVI,QTIME
字段值是图象数据或存储图象数据的文件名(包含URL路径)没有默认的字段类型,所以必须指定一种字段类型
BDAY无定义字段值是出生日期的数据,有两种表示方法:
1)、基于ISO8601的基本格式:<month>
2)、基于ISO8601的扩展格式:--其中年是四个字符表示,月份和日期是两个字符表示
ADRDOM,INTL(),POSTAL(),PARCEL(),
HOME,WORK(
)
分7个字段表示地址的值:
[Post Office Address];[Extended Address];
[Street];[Locality];[Region];[Postal code];
[Country]
第一个字段基于X.500标准,其余字段基于X.520标准
LABELDOM,INTL(),POSTAL(),PARCEL(),
HOME,WORK(
)
字段值是一种日常表示地址的方法基于X.520的普通名字语义规则
TELPREF,WORK,HOME,VOICE(*),
FAX,MSG,CELL,PAGER,BBS,MODEM,
CAR,ISDN,VIDEO
字段值是基于X.520的电话号码表示方法,这种数据格式不能保证能被拨号程序直接使用,具体的数据格式解析应由拨号程序解决。
EMAILAOL,AppleLink,ATTMail,
CIS,eWorld,INTERNET(*),IBMMail,
MCIMail,POWERSHARE,
PRODIGY,TLX,X400
字段值是电子邮件地址第二栏列出的是该字段类型的一部份,可能会有其它的类型
EMAILER无定义字段值是电子邮件软件的名称
TZ无定义字段值是某地时间相对于UTC(Coordianted Universal Time)的时差(时区),用正负值表示相对值,UTC以西则为负值,以东为正值,值表示根据ISO8610标准,有两种形式:
1)、<+/-><hour(two digit)><minute(two digit)>
2)、<+/-><hour(two digit)>:<minute(two digit)>
GEO无定义字段值表示某地的经度(longitude)和纬度(latitude)的地理位置信息,北纬为正值,南纬为负值,东经为正值,西经为负值:
 <+/->[longitude value],<+/->[latitude value]
TITLE无定义字段值表示某人头衔名
ROLE无定义字段值表示一个人的职业名称或承担的角色或其它商务类型,基于X.520商务类型定义。
LOGOGIF,CGM,WMF,BMP,MET,PMB,
DIB,PICT,TIFF,PDF,PS,JPEG,
MPEG,MPEG2,AVI,QTIME
字段值表示某种标识的图像或肖像没有默认字段类型,所以必须指定一种字段类型
AGENT无定义字段值表示与vCard对象所定义的人有关系的另一个人的信息(如管理员,助手,秘书等),字段值是一个完整的vCard数据包
ORG无定义字段值表示一个机构名称,基于X.520标准:
[Organization Name];[Organization Unit]
[;additional Organizational Unit;…]
NOTE无定义字段值为与本vCard对象有关的备注或提示信息,基于X.520标准
REV无定义字段值表示最后一次的对本vCard对象的更新时间,时间采用日程表中的时间表示方法,基于ISO8601标准:
1)、<year(four digits)><month(two digits)><day(two digits)>T<hour(two digits)><minitue(two digits)><second(two digits)>[time zone]
2)、<year(four digits)>-<month(two digits)>-<day(two digits)>T<hour(two digits)>:<minitue(two digits)>:<second(two digits)>[time zone]
SOUNDWAVE,PCM,AIFF字段值表示与本vCard对象有关的发音的声音数据,如该字段没有与其它字段分组,则该字段表示FN字段值的发音,字段值可以是二制的声音数据,也可以用其它单词表示的发音方法。没有默认字段类型,当没有指定字段类型时,字段值为表示发音方法的文件或单词
URL无定义字段值表示统一资源位置(Uniform Resource Locator),基于IETF RFC 1738定义。
UID无定义字段值表示本vCard对象的GUID号或本vCard对象将被更新的URL地址
VERSION无定义字段值表示本vCard对象的版本号该字段是必选字段,在更早以前的版本是可选
KEYX509,PGP该字段值表示加密密钥,默认的格式是明文格式(clear-text)没有默认字段类型,字段类型必需被定义
X-无定义该字段值由用户自定义字段参数值由用户自选

注:1、字段类型后带“*”表示是默认字段类型;
  2、字段值中若以“;”进行值分类的,当值中本身还包含有“;”或“\r\n”则必须进行转义,相应地用“;”和“\”CRCF来进行转义
PS:内容来源于网络,本文案例中仅做了部分实践,感兴趣的可自行实践

3.包含个人信息的vCard文件样例

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

三、实现

1.所需jar包

温馨提示:先看完再选择是否下载
在这里插入图片描述

2.二维码处理工具类

TwoDimensionCodeImage.java

package util;

import java.awt.image.BufferedImage;

import jp.sourceforge.qrcode.data.QRCodeImage;

public class TwoDimensionCodeImage implements QRCodeImage {

	BufferedImage bufImg;

	public TwoDimensionCodeImage(BufferedImage bufImg) {
		this.bufImg = bufImg;
	}

	@Override
	public int getHeight() {
		return bufImg.getHeight();
	}

	@Override
	public int getPixel(int x, int y) {
		return bufImg.getRGB(x, y);
	}

	@Override
	public int getWidth() {
		return bufImg.getWidth();
	}

}

TwoDimensionCode.java

package util;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;

import jp.sourceforge.qrcode.QRCodeDecoder;
import jp.sourceforge.qrcode.exception.DecodingFailedException;

import com.swetake.util.Qrcode;

public class TwoDimensionCode {

	/**
	 * 生成二维码(QRCode)图片
	 * 
	 * @param content
	 *            存储内容
	 * @param imgPath
	 *            图片路径
	 */
	public static void encoderQRCode(String content, String imgPath) {
		encoderQRCode(content, imgPath, "png", 2);
	}

	/**
	 * 生成二维码(QRCode)图片
	 * 
	 * @param content
	 *            存储内容
	 * @param output
	 *            输出流
	 */
	public static void encoderQRCode(String content, OutputStream output) {
		encoderQRCode(content, output, "png", 2);
	}

	/**
	 * 生成二维码(QRCode)图片
	 * 
	 * @param content
	 *            存储内容
	 * @param imgPath
	 *            图片路径
	 * @param imgType
	 *            图片类型
	 */
	public static void encoderQRCode(String content, String imgPath,
			String imgType) {
		encoderQRCode(content, imgPath, imgType, 2);
	}

	/**
	 * 生成二维码(QRCode)图片
	 * 
	 * @param content
	 *            存储内容
	 * @param output
	 *            输出流
	 * @param imgType
	 *            图片类型
	 */
	public static void encoderQRCode(String content, OutputStream output,
			String imgType) {
		encoderQRCode(content, output, imgType, 2);
	}

	/**
	 * 生成二维码(QRCode)图片
	 * 
	 * @param content
	 *            存储内容
	 * @param imgPath
	 *            图片路径
	 * @param imgType
	 *            图片类型
	 * @param size
	 *            二维码尺寸
	 */
	public static void encoderQRCode(String content, String imgPath,
			String imgType, int size) {
		try {
			BufferedImage bufImg = qRCodeCommon(content, imgType, size);

			File imgFile = new File(imgPath);
			// 生成二维码QRCode图片
			ImageIO.write(bufImg, imgType, imgFile);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成二维码(QRCode)图片
	 * 
	 * @param content
	 *            存储内容
	 * @param output
	 *            输出流
	 * @param imgType
	 *            图片类型
	 * @param size
	 *            二维码尺寸
	 */
	public static void encoderQRCode(String content, OutputStream output,
			String imgType, int size) {
		try {
			BufferedImage bufImg = qRCodeCommon(content, imgType, size);
			// 生成二维码QRCode图片
			ImageIO.write(bufImg, imgType, output);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成二维码(QRCode)图片的公共方法
	 * 
	 * @param content
	 *            存储内容
	 * @param imgType
	 *            图片类型
	 * @param size
	 *            二维码尺寸
	 * @return
	 */
	private static BufferedImage qRCodeCommon(String content, String imgType,
			int size) {
		BufferedImage bufImg = null;
		size = 14;
		try {
			Qrcode qrcodeHandler = new Qrcode();
			// 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小
			qrcodeHandler.setQrcodeErrorCorrect('M');
			qrcodeHandler.setQrcodeEncodeMode('B');
			// 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
			qrcodeHandler.setQrcodeVersion(size);
			// 获得内容的字节数组,设置编码格式
			byte[] contentBytes = content.getBytes("utf-8");
			// 图片尺寸
			// int imgSize = 67 + 12 * (size - 1);
			int imgSize = 67 + 12 * (size - 1);

			// System.out.println(imgSize);

			bufImg = new BufferedImage(imgSize, imgSize,
					BufferedImage.TYPE_INT_RGB);
			Graphics2D gs = bufImg.createGraphics();
			// 设置背景颜色
			gs.setBackground(Color.WHITE);
			gs.clearRect(0, 0, imgSize, imgSize);

			// 设定图像颜色> BLACK
			gs.setColor(Color.BLACK);
			// 设置偏移量,不设置可能导致解析出错
			int pixoff = 2;
			// 输出内容> 二维码
			if (contentBytes.length > 0 && contentBytes.length < 800) {

				boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);
				for (int i = 0; i < codeOut.length; i++) {
					for (int j = 0; j < codeOut.length; j++) {
						if (codeOut[j][i]) {
							gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
						}
					}
				}
			} else {
				throw new Exception("QRCode content bytes length = "
						+ contentBytes.length + " not in [0, 800].");
			}
			gs.dispose();
			bufImg.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bufImg;
	}

	/**
	 * 解析二维码(QRCode)
	 * 
	 * @param imgPath
	 *            图片路径
	 * @return
	 */
	public static String decoderQRCode(String imgPath) throws Exception {
		// QRCode 二维码图片的文件
		File imageFile = new File(imgPath);
		BufferedImage bufImg = null;
		String content = null;
		try {
			bufImg = ImageIO.read(imageFile);
			QRCodeDecoder decoder = new QRCodeDecoder();
			content = new String(decoder.decode(new TwoDimensionCodeImage(
					bufImg)), "utf-8");
		} catch (IOException e) {
			// System.out.println("Error: " + e.getMessage());
			// e.printStackTrace();
		} catch (DecodingFailedException dfe) {
			// System.out.println("Error: " + dfe.getMessage());
			// dfe.printStackTrace();
		}
		return content;
	}

	/**
	 * 解析二维码(QRCode)
	 * 
	 * @param input
	 *            输入流
	 * @return
	 */
	public static String decoderQRCode(InputStream input) {
		BufferedImage bufImg = null;
		String content = null;
		try {
			bufImg = ImageIO.read(input);
			QRCodeDecoder decoder = new QRCodeDecoder();
			content = new String(decoder.decode(new TwoDimensionCodeImage(
					bufImg)), "utf-8");
		} catch (IOException e) {
			System.out.println("Error: " + e.getMessage());
			e.printStackTrace();
		} catch (DecodingFailedException dfe) {
			System.out.println("Error: " + dfe.getMessage());
			dfe.printStackTrace();
		}
		return content;
	}

}

3.异常处理类

Exceptions.java

package util;

import java.io.PrintWriter;
import java.io.StringWriter;

import javax.servlet.http.HttpServletRequest;

/**
 * 关于异常的工具类.
 */
public class Exceptions {

	/**
	 * 将CheckedException转换为UncheckedException.
	 */
	public static RuntimeException unchecked(Exception e) {
		if (e instanceof RuntimeException) {
			return (RuntimeException) e;
		} else {
			return new RuntimeException(e);
		}
	}

	/**
	 * 将ErrorStack转化为String.
	 */
	public static String getStackTraceAsString(Throwable e) {
		if (e == null) {
			return "";
		}
		StringWriter stringWriter = new StringWriter();
		e.printStackTrace(new PrintWriter(stringWriter));
		return stringWriter.toString();
	}

	/**
	 * 判断异常是否由某些底层的异常引起.
	 */
	public static boolean isCausedBy(Exception ex,
			Class<? extends Exception>... causeExceptionClasses) {
		Throwable cause = ex.getCause();
		while (cause != null) {
			for (Class<? extends Exception> causeClass : causeExceptionClasses) {
				if (causeClass.isInstance(cause)) {
					return true;
				}
			}
			cause = cause.getCause();
		}
		return false;
	}

	/**
	 * 在request中获取异常类
	 * 
	 * @param request
	 * @return
	 */
	public static Throwable getThrowable(HttpServletRequest request) {
		Throwable ex = null;
		if (request.getAttribute("exception") != null) {
			ex = (Throwable) request.getAttribute("exception");
		} else if (request.getAttribute("javax.servlet.error.exception") != null) {
			ex = (Throwable) request
					.getAttribute("javax.servlet.error.exception");
		}
		return ex;
	}

}

4.实体类

Person.java

package test;

/**
 * 个人信息 实体类
 */
public class Person {
	// 仅用于演示效果,勿纠结细节(如字段类型、合理性等)
	private String name; // 姓名
	private String position; // 职位
	private String department; // 部门
	private String phone; // 电话
	private String email; // 邮箱
	private String address; // 地址
	private String url; // 官网

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPosition() {
		return position;
	}

	public void setPosition(String position) {
		this.position = position;
	}

	public String getDepartment() {
		return department;
	}

	public void setDepartment(String department) {
		this.department = department;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

}

5.功能实现类

StaffMain.java

package test;

import java.io.IOException;

import util.TwoDimensionCode;

public class StaffMain {
	public static void main(String[] args) throws IOException {

		Person person = new Person();
		person.setName("李四");
		person.setDepartment("销售部");
		person.setPosition("销售总监");
		person.setPhone("18888888888");
		person.setEmail("xxx@163.com");
		person.setAddress("北京市XX区XX大厦XX层XXX室");
		person.setUrl("www.xxxxxxxxx.cn");
		// 生成用户二维码
		String realPath = "L:/qrcode/";
		String name = person.getName() + ".png"; // 二维码的图片名
		String filePath = realPath + name; // 二维码路径
		String content = "BEGIN:VCARD\r\nVERSION:3.0";
		content += "\r\nN:" + person.getName();
		content += "\r\nTEL:" + person.getPhone();
		content += "\r\nEMAIL;TYPE=WORK:" + person.getEmail();
		content += "\r\nORG:" + person.getPosition();
		content += "\r\nTITLE:" + person.getDepartment();
		content += "\r\nADR;TYPE=WORK:" + person.getAddress();
		content += "\r\nEND:VCARD";
		System.out.println(content);
		TwoDimensionCode.encoderQRCode(content, filePath, "png");// 执行生成二维码
	}
}

6.控制台

在这里插入图片描述

7.执行效果

在这里插入图片描述

8.二维码扫描

在这里插入图片描述在这里插入图片描述在这里插入图片描述

总结

到此,该功能已实现,完整版代码,不方便下载的私信留邮箱,看到后回复

标签:段值,扫码,return,String,vCard,content,通讯录,import,public
来源: https://blog.csdn.net/super_DuoLa/article/details/116697473