修改逻辑 & 添加单元测试

This commit is contained in:
wangkang
2017-08-18 11:22:24 +08:00
parent 818a4d2b97
commit aef77d2408
9 changed files with 212 additions and 91 deletions
@@ -107,7 +107,7 @@ public class FileController implements IFileController {
//输出文件
final int buffInt = 1024;
byte[] buff = new byte[buffInt];
OutputStream os;
OutputStream os = null;
BufferedInputStream bis = null;
try { //NOSONAR
os = response.getOutputStream();
@@ -122,8 +122,8 @@ public class FileController implements IFileController {
if (bis != null) {
bis.close();
}
if (bis != null) {
bis.close();
if (os != null) {
os.close();
}
}
}
@@ -39,12 +39,6 @@ public class QrCodeRequest implements Serializable {
@ApiModelProperty(value = "尺寸(默认200)", required = false, dataType = "int")
private Integer size = QrCodeOptions.DEF_SIZE;
/**
* 生成图片的类型(默认 : png)
*/
@ApiModelProperty(value = "生成图片的类型(默认 : png)", required = false, dataType = "string")
private String picType = "png";
/**
* 绘制二维码的背景色(默认0xffffffff)
*/
@@ -16,6 +16,11 @@ public class QrCodeOptions {
*/
public static final int DEF_SIZE = 200;
/**
* 默认文件类型
*/
public static final String DEF_PIC_TYPE = "png";
/**
* 塞入二维码的信息
*/
@@ -57,11 +62,4 @@ public class QrCodeOptions {
*/
private Map<EncodeHintType, Object> hints;
/**
* 生成二维码图片的格式 png, jpg
*/
private String picType = "png";
}
@@ -16,8 +16,10 @@ import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
/**
* QrcodeService
@@ -69,10 +71,37 @@ public class QrcodeService {
* @throws IOException IOException
* @throws WriterException WriterException
*/
public String parse(QrCodeRequest request) throws IOException, WriterException {
public String parseString(QrCodeRequest request) throws IOException, WriterException {
return this.asString(this.build(request));
}
/**
* 生成二维码
*
* @param request 参数
* @return 结果
* @throws IOException IOException
* @throws WriterException WriterException
*/
public BufferedImage parseBufferedImage(QrCodeRequest request) throws IOException, WriterException {
return this.asBufferedImage(this.build(request));
}
/**
* 生成二维码
*
* @param request request
* @param absFileName absFileName
* @throws WriterException WriterException
* @throws IOException IOException
*/
public void parseFile(QrCodeRequest request, String absFileName) throws WriterException, IOException {
File file = new File(absFileName);
file.mkdirs();
BufferedImage bufferedImage = this.asBufferedImage(this.build(request));
ImageIO.write(bufferedImage, QrCodeOptions.DEF_PIC_TYPE, file);
}
/**
* 将二维码转化为string
*
@@ -84,7 +113,7 @@ public class QrcodeService {
private String asString(QrCodeOptions qrCodeOptions) throws IOException, WriterException {
BufferedImage bufferedImage = asBufferedImage(qrCodeOptions);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, qrCodeOptions.getPicType(), outputStream);
ImageIO.write(bufferedImage, QrCodeOptions.DEF_PIC_TYPE, outputStream);
return Base64Util.encode(outputStream);
}
@@ -109,15 +138,15 @@ public class QrcodeService {
*/
private QrCodeOptions build(QrCodeRequest request) throws IOException { //NOSONAR
//常量
final int num3 = 3;
final int num4 = 4;
//处理参数
QrCodeOptions op = new QrCodeOptions();
op.setMsg(request.getContent());
op.setPicType(request.getPicType());
op.setW(request.getSize() == null ? (op.getH() == null ? QrCodeOptions.DEF_SIZE : op.getH()) : request.getSize()); //NOSONAR
op.setH(request.getSize() == null ? (op.getW() == null ? QrCodeOptions.DEF_SIZE : op.getW()) : request.getSize()); //NOSONAR
// 设置精度参数
EnumMap<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
Map<EncodeHintType, Object> hints = new HashMap<>(num3); //NOSONAR
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, request.getCharset());
hints.put(EncodeHintType.MARGIN, request.getPadding() == null ? 1 : request.getPadding() < 0 ? 0 : request.getPadding() > num4 ? num4 : request.getPadding()); //NOSONAR
@@ -150,9 +179,12 @@ public class QrcodeService {
}
op.setDrawOptions(drawOptions);
//logo 相关
final int num12 = 12;
LogoOptions logoOptions = new LogoOptions();
logoOptions.setLogoStyle(LogoStyle.NORMAL);
logoOptions.setBorder(false);
logoOptions.setRate(num12);
if (StringUtils.isNotBlank(request.getLogo())) {
final int num12 = 12;
LogoOptions logoOptions = new LogoOptions();
logoOptions.setLogo(ImageUtil.getByPath(request.getLogo()));
logoOptions.setRate(request.getLogoRate() == null ? num12 : request.getLogoRate());
logoOptions.setBorder(request.isLogoBorder());
@@ -164,23 +196,32 @@ public class QrcodeService {
op.setLogoOptions(logoOptions);
}
//探测图形
DetectOptions detectOptions = new DetectOptions();
if (StringUtils.isNotBlank(request.getDetectImg())) {
DetectOptions detectOptions = new DetectOptions();
detectOptions.setDetectImg(ImageUtil.getByPath(request.getDetectImg()));
op.setDetectOptions(detectOptions);
} else {
DetectOptions detectOptions = new DetectOptions();
if (StringUtils.isNotBlank(request.getDetectInColor())) {
detectOptions.setInColor(ColorUtil.int2color(NumUtil.decode2int(request.getDetectInColor(), null)));
}
if (StringUtils.isNotBlank(request.getDetectOutColor())) {
detectOptions.setOutColor(ColorUtil.int2color(NumUtil.decode2int(request.getDetectOutColor(), null)));
}
op.setDetectOptions(detectOptions);
}
if (detectOptions.getOutColor() == null && detectOptions.getInColor() == null) {
detectOptions.setInColor(drawOptions.getPreColor());
detectOptions.setOutColor(drawOptions.getPreColor());
} else if (detectOptions.getOutColor() == null) {
detectOptions.setOutColor(detectOptions.getOutColor());
} else if (detectOptions.getInColor() == null) {
detectOptions.setInColor(detectOptions.getInColor());
}
op.setDetectOptions(detectOptions);
// 背景相关
BgImgOptions bgImgOptions = new BgImgOptions();
bgImgOptions.setBgImgStyle(BgImgStyle.OVERRIDE);
bgImgOptions.setOpacity(0.85f);
if (StringUtils.isNotBlank(request.getBgImg())) {
BgImgOptions bgImgOptions = new BgImgOptions();
bgImgOptions.setBgImg(ImageUtil.getByPath(request.getBgImg()));
bgImgOptions.setBgw(request.getBgw() == null ? 0 : request.getBgw());
bgImgOptions.setBgh(request.getBgh() == null ? 0 : request.getBgh());
@@ -20,6 +20,11 @@ import java.awt.image.BufferedImage;
@Slf4j
public class QrCodeUtil {
/**
* QUIET_ZONE_SIZE
*/
private static final int QUIET_ZONE_SIZE = 4;
/**
* 私有化构造函数
*/
@@ -27,11 +32,6 @@ public class QrCodeUtil {
}
/**
* QUIET_ZONE_SIZE
*/
private static final int QUIET_ZONE_SIZE = 4;
/**
* 对 zxing 的 QRCodeWriter 进行扩展, 解决白边过多的问题
*
@@ -133,9 +133,7 @@ public class QrCodeUtil {
int realQrCodeHeight = qrCodeConfig.getH();
if (qrCodeWidth != realQrCodeWidth || qrCodeHeight != realQrCodeHeight) {
BufferedImage tmp = new BufferedImage(realQrCodeWidth, realQrCodeHeight, BufferedImage.TYPE_INT_RGB);
tmp.getGraphics().drawImage(
qrCode.getScaledInstance(realQrCodeWidth, realQrCodeHeight,
Image.SCALE_SMOOTH), 0, 0, null);
tmp.getGraphics().drawImage(qrCode.getScaledInstance(realQrCodeWidth, realQrCodeHeight, Image.SCALE_SMOOTH), 0, 0, null);
qrCode = tmp;
}
/**
@@ -174,13 +172,11 @@ public class QrCodeUtil {
if (qrCodeSize >= expectSize) {
return 0;
}
int scale = expectSize / qrCodeSize;
int abs = expectSize - scale * qrCodeSize;
if (abs < expectSize * 0.15) {
return 0;
}
return scale;
}
@@ -15,10 +15,13 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 描述 : IQrcodeController
* <p/>
* 此实现参考自 : https://my.oschina.net/u/566591/blog/1457164
*
* @author Administrator
*/
@@ -67,14 +70,14 @@ public interface IQrcodeController {
RestResponse<String> decode(String path) throws FormatException, ChecksumException, NotFoundException, IOException;
/**
* 生成二维码
* 生成二维码(base64编码)
*
* @param qrCodeRequest 参数
* @return 结果
* @throws IOException IOException
* @throws IOException IOException
* @throws WriterException WriterException
*/
@ApiOperation(value = "QRCODE_3", notes = "生成二维码")
@ApiOperation(value = "QRCODE_3", notes = "生成二维码(base64编码)")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "header", name = "rmsApplicationName", value = "rms应用名称", required = true, dataType = "string"),
@ApiImplicitParam(paramType = "header", name = "rmsSign", value = "rms认证秘钥", required = true, dataType = "string"),
@@ -83,4 +86,21 @@ public interface IQrcodeController {
@RequestMapping(value = "gen", method = RequestMethod.POST)
RestResponse<String> parse(@RequestBody QrCodeRequest qrCodeRequest) throws IOException, WriterException;
/**
* 生成二维码(文件流)
*
* @param qrCodeRequest 参数
* @param response 响应参数
* @throws IOException IOException
* @throws WriterException WriterException
*/
@ApiOperation(value = "QRCODE_4", notes = "生成二维码(文件流)")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "header", name = "rmsApplicationName", value = "rms应用名称", required = true, dataType = "string"),
@ApiImplicitParam(paramType = "header", name = "rmsSign", value = "rms认证秘钥", required = true, dataType = "string"),
@ApiImplicitParam(paramType = "header", name = "rmsServiceCode", value = "rms接口编号", required = true, dataType = "string")
})
@RequestMapping(value = "download", method = RequestMethod.POST)
void download(@RequestBody QrCodeRequest qrCodeRequest, HttpServletResponse response) throws IOException, WriterException;
}
@@ -4,8 +4,10 @@ import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.WriterException;
import org.itkk.udf.core.ApplicationConfig;
import org.itkk.udf.core.RestResponse;
import org.itkk.udf.qrcode.domain.QrCodeRequest;
import org.itkk.udf.qrcode.option.QrCodeOptions;
import org.itkk.udf.qrcode.service.QrcodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
@@ -13,7 +15,10 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
/**
* QrcodeController
@@ -21,6 +26,12 @@ import java.io.IOException;
@RestController
public class QrcodeController implements IQrcodeController {
/**
* 描述 : applicationConfig
*/
@Autowired
private ApplicationConfig applicationConfig;
/**
* qrcodeService
*/
@@ -39,6 +50,28 @@ public class QrcodeController implements IQrcodeController {
@Override
public RestResponse<String> parse(@RequestBody QrCodeRequest qrCodeRequest) throws IOException, WriterException {
return new RestResponse<>(this.qrcodeService.parse(qrCodeRequest));
return new RestResponse<>(this.qrcodeService.parseString(qrCodeRequest));
}
@Override
public void download(@RequestBody QrCodeRequest qrCodeRequest, HttpServletResponse response) throws IOException, WriterException {
//常量
final String contentType = "image/png";
//输出流
OutputStream os = null;
try {
//设置response
response.setCharacterEncoding(applicationConfig.getEncoding());
response.setContentType(contentType);
//生成二维码
BufferedImage bufferedImage = this.qrcodeService.parseBufferedImage(qrCodeRequest);
//输出
os = response.getOutputStream();
ImageIO.write(bufferedImage, QrCodeOptions.DEF_PIC_TYPE, os);
} finally {
if (os != null) {
os.close();
}
}
}
}
@@ -0,0 +1,89 @@
package org.itkk.udf.qrcode;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.WriterException;
import org.itkk.udf.qrcode.domain.QrCodeRequest;
import org.itkk.udf.qrcode.option.LogoStyle;
import org.itkk.udf.qrcode.service.QrcodeService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
/**
* QrCodeServiceTest
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = QrcodeService.class)
public class QrCodeServiceTest {
/**
* qrcodeService
*/
@Autowired
private QrcodeService qrcodeService;
@Test
public void testDecode() throws FormatException, ChecksumException, NotFoundException, IOException {
String img = "https://static.oschina.net/uploads/img/201707/09205944_0PzS.jpg";
String ans = qrcodeService.decode(img);
System.out.println(ans);
}
@Test
public void testParseString() throws IOException, WriterException {
String msg = "http://itkk.org:81";
QrCodeRequest request = new QrCodeRequest();
request.setContent(msg);
String out = qrcodeService.parseString(request);
System.out.println("普通二维码 : <img src=\"data:image/png;base64," + out + "\" />");
request = new QrCodeRequest();
request.setContent(msg);
request.setSize(300);
request.setPreColor("0xffff0000");
request.setBgColor("0xffffffff");
request.setPadding(0);
out = qrcodeService.parseString(request);
System.out.println("生成红色的二维码 300x300, 无边框 : <img src=\"data:image/png;base64," + out + "\" />");
String logo = "https://static.oschina.net/uploads/user/283/566591_100.jpeg";
request = new QrCodeRequest();
request.setContent(msg);
request.setSize(300);
request.setPreColor("0xffff0000");
request.setBgColor("0xffffffff");
request.setPadding(0);
request.setLogo(logo);
request.setLogoBorderColor("0xff808080");
request.setLogoBorder(true);
out = qrcodeService.parseString(request);
System.out.println("生成带logo的二维码 : <img src=\"data:image/png;base64," + out + "\" />");
logo = "https://static.oschina.net/uploads/user/283/566591_100.jpeg";
request = new QrCodeRequest();
request.setContent(msg);
request.setSize(300);
request.setPreColor("0xff0000ff");
request.setBgColor("0xffffffff");
request.setDetectOutColor("0xff00FF00");
request.setDetectInColor("0xffff0000");
request.setPadding(1);
request.setLogo(logo);
request.setLogoRate(15);
request.setLogoStyle(LogoStyle.ROUND.name());
request.setLogoBorderColor("0xff808080");
request.setLogoBorder(true);
request.setBgImg(logo);
request.setBgOpacity(0.8f);
out = qrcodeService.parseString(request);
System.out.println("无边框, 重新着色位置探测图像, 设置背景 : <img src=\"data:image/png;base64," + out + "\" />");
}
}
@@ -1,50 +0,0 @@
package org.itkk.udf.qrcode;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import org.itkk.udf.qrcode.domain.QrCodeRequest;
import org.itkk.udf.qrcode.service.QrcodeService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
/**
* QrCodeTest
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = QrcodeService.class)
public class QrCodeTest {
/**
* qrcodeService
*/
@Autowired
private QrcodeService qrcodeService;
@Test
public void testDepaseQrCode() throws FormatException, ChecksumException, NotFoundException, IOException {
String img = "https://static.oschina.net/uploads/img/201707/09205944_0PzS.jpg";
String ans = qrcodeService.decode(img);
System.out.println(ans);
}
@Test
public void testGenQrCode1() {
String msg = "http://itkk.org:81";
try {
QrCodeRequest request = new QrCodeRequest();
request.setContent(msg);
String out = qrcodeService.parse(request);
System.out.println("<img src=\"data:image/png;base64," + out + "\" />");
} catch (Exception e) {
e.printStackTrace();
}
}
}