diff --git a/udf-starter-file/src/main/java/org/itkk/udf/file/web/FileController.java b/udf-starter-file/src/main/java/org/itkk/udf/file/web/FileController.java index 2b7f401..91017bc 100644 --- a/udf-starter-file/src/main/java/org/itkk/udf/file/web/FileController.java +++ b/udf-starter-file/src/main/java/org/itkk/udf/file/web/FileController.java @@ -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(); } } } diff --git a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/domain/QrCodeRequest.java b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/domain/QrCodeRequest.java index 61f89ac..fdc3ffe 100644 --- a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/domain/QrCodeRequest.java +++ b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/domain/QrCodeRequest.java @@ -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) */ diff --git a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/option/QrCodeOptions.java b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/option/QrCodeOptions.java index f23ea35..f9c877a 100644 --- a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/option/QrCodeOptions.java +++ b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/option/QrCodeOptions.java @@ -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 hints; - /** - * 生成二维码图片的格式 png, jpg - */ - private String picType = "png"; - - - } diff --git a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/service/QrcodeService.java b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/service/QrcodeService.java index d61dee6..368023a 100644 --- a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/service/QrcodeService.java +++ b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/service/QrcodeService.java @@ -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 hints = new EnumMap<>(EncodeHintType.class); + Map 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()); diff --git a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/utils/QrCodeUtil.java b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/utils/QrCodeUtil.java index 3fcfe10..9e093fe 100644 --- a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/utils/QrCodeUtil.java +++ b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/utils/QrCodeUtil.java @@ -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; } diff --git a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/web/IQrcodeController.java b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/web/IQrcodeController.java index c5b9bcd..caed8a5 100644 --- a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/web/IQrcodeController.java +++ b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/web/IQrcodeController.java @@ -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 + *

+ * 此实现参考自 : https://my.oschina.net/u/566591/blog/1457164 * * @author Administrator */ @@ -67,14 +70,14 @@ public interface IQrcodeController { RestResponse 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 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; + } diff --git a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/web/QrcodeController.java b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/web/QrcodeController.java index 56316dd..9880fc6 100644 --- a/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/web/QrcodeController.java +++ b/udf-starter-qrcode/src/main/java/org/itkk/udf/qrcode/web/QrcodeController.java @@ -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 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(); + } + } } } diff --git a/udf-starter-qrcode/src/test/java/org/itkk/udf/qrcode/QrCodeServiceTest.java b/udf-starter-qrcode/src/test/java/org/itkk/udf/qrcode/QrCodeServiceTest.java new file mode 100644 index 0000000..361a5df --- /dev/null +++ b/udf-starter-qrcode/src/test/java/org/itkk/udf/qrcode/QrCodeServiceTest.java @@ -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("普通二维码 : "); + + 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, 无边框 : "); + + 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的二维码 : "); + + 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("无边框, 重新着色位置探测图像, 设置背景 : "); + + } + +} diff --git a/udf-starter-qrcode/src/test/java/org/itkk/udf/qrcode/QrCodeTest.java b/udf-starter-qrcode/src/test/java/org/itkk/udf/qrcode/QrCodeTest.java deleted file mode 100644 index b98d3c7..0000000 --- a/udf-starter-qrcode/src/test/java/org/itkk/udf/qrcode/QrCodeTest.java +++ /dev/null @@ -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(""); - } catch (Exception e) { - e.printStackTrace(); - } - } - -}