湖北省建设厅官方网站八大员,wordpress中文,软件技术方案模板,大航母网站建设与服务之前有遇到一个问题 问题背景#xff1a;项目中#xff0c;有一个功能#xff0c;管理端可以将客户创建的小程序码下载到本地#xff0c;方便客户将对应门店的小程序码打印出来并张贴到门店#xff0c;做门店的引流和会员入会。 具体问题#xff1a;当小程序码的数量较少… 之前有遇到一个问题 问题背景项目中有一个功能管理端可以将客户创建的小程序码下载到本地方便客户将对应门店的小程序码打印出来并张贴到门店做门店的引流和会员入会。 具体问题当小程序码的数量较少的时候我们是后端将小程序码的分组信息和小程序码的图片以树的数据结构形式返回给前端由前端拿到分组信息和小程序图片链接在前端进行下载小程序码图片并将分组信息拼接在小程序码的下方类似这样 但是当这个门店的结构复杂之后小程序码的数量也多了起来由前端来下载就显得非常让人焦灼了前端只能使用下载的这台电脑的性能来一张一张的下载小程序码并拼接门店的信息1000多张小程序码的话就需要10分钟左右的等待时间有的客户的电脑性能比较差的话干脆就没办法下载怎么办呢 一句话放后端并行下载呗然后直接返回zip包的流数据文件给前端不就行了。。。 当时接到这个任务我也天真的认为搞个线程并行下载然后打包不就OK了么能有多费事呢服务器随随便便不就16核64G的配置下载个文件就算网络差点千把个图片还不是分分钟的事儿嘛领导面前胸口拍得梆梆响小事一桩嘛~~~ 下载倒是好说并发 CountDownLatch cdl new CountDownLatch(size); 控制下下载的次序下载完再一起打包。。。 但是把文字怎么搞到这张小程序码图片的下面呢又不能拉伸这张图片那就要把文字先转成图片跟小程序码图片宽度保持一致 a.先把远程的图片下载到本地
String localFilePath D:\\Download\\0402 File.separator;
String localFileName test3.png;
downloadFile(http://0.0.0.0:8080/photo/gh_ff959c80f0d7_1280.jpg, localFilePath, localFileName);/*** 下载远程文件并保存到本地*/
public static void downloadFile(String remoteFilePath, String localFilePath, String fileName) {FileUtil.mkdir(localFilePath);ReadableByteChannel rbc null;FileOutputStream fos null;try {URL website new URL(remoteFilePath);rbc Channels.newChannel(website.openStream());fos new FileOutputStream(localFilePath fileName);fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);} catch (Exception e) {log.warn(e.getMessage());} finally {IOUtils.closeQuietly(fos);IOUtils.closeQuietly(rbc);}} b.将第一行文字和第二行文字转换成跟小程序码图片一样宽度的图片 /*** 小程序码 导出组名 二维码名 字体*/public static final String SOURCE_HAN_SANS 思源黑体 CN Regular;/*** 小程序码 导出 二维码名 字号*/public static final int FONT_SIZE_TITLE 24;/*** 小程序码 导出组名 字号*/public static final int FONT_SIZE_GROUP_NAME 14;/*** 小程序码 导出二维码图片 缩略图 宽度*/public static final int MA_QR_CODE_IMAGE_WIDTH 552;/*** 小程序码 导出二维码图片 缩略图 高度*/public static final int MA_QR_CODE_IMAGE_HEIGHT 552;/*** 小程序码 文字生成图片 背景高度*/public static final int BACK_GROUND_IMAGE_HEIGHT 35;/*** 小程序码 导出二维码名 每行长度*/public static final int MA_QR_CODE_SPLIT_SIZE 21;/*** 小程序码 导出组名 每行长度*/public static final int MA_GROUP_SPLIT_SIZE 38;//第一行文字
String fileName ZSHMD上海市浦东新区东方体育中心万达购物中心店;
String targetFile localFilePath test3_t1.png;
TextToImage.textToImage(TextToImage.ImageContent.buildOf(MA_QR_CODE_IMAGE_WIDTH, MA_QR_CODE_SPLIT_SIZE, Color.BLACK, SOURCE_HAN_SANS, FONT_SIZE_TITLE, fileName, targetFile));
//第二行文字
String groupFullName 全部-中国-上海-浦东新区-三林镇;
String groupTargetFile localFilePath test3_t2.png;
TextToImage.textToImage(TextToImage.ImageContent.buildOf(MA_QR_CODE_IMAGE_WIDTH, MA_GROUP_SPLIT_SIZE, Color.GRAY, SOURCE_HAN_SANS, FONT_SIZE_GROUP_NAME, groupFullName, groupTargetFile));
工具类方法 /*** 将文字转换为png图片*/public static void textToImage(ImageContent content) throws IOException {//小程序码 文字生成图片 背景高度String contentText content.getText();if (StringUtils.isEmpty(contentText)) {return;}String[] texts contentText.split((?\\G.{ content.getSplitSize() }));int height texts.length * BACK_GROUND_IMAGE_HEIGHT;//创建图片int width content.getWidth();BufferedImage bufferedImage new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics2D graphics bufferedImage.createGraphics();//设置背景graphics.fillRect(0, 0, width, height);//定义字体Font font new Font(content.getFontName(), Font.PLAIN, content.getFontSize());// 防止生成的文字带有锯齿graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);//设置颜色graphics.setColor(content.getColor());//设置字体graphics.setFont(font);//写入 getWordWidth 计算该字体文本的长度 居中Lists.mutable.of(texts).forEachWithIndex((x, i) -graphics.drawString(x, (width - getWordWidth(font, x)) / 2, 20 30 * i));graphics.dispose();ImageIO.write(bufferedImage, PNG, new File(content.getTargetFile()));}
工具类-内部类 Datapublic static class ImageContent{private int width;private int splitSize;private Color color;private String fontName;private int fontSize;private String text;private String targetFile;public static ImageContent buildOf(int maQrCodeImageWidth, int maQrCodeSplitSize, Color color, String fontName, int fontSize, String text, String targetFile) {ImageContent content new ImageContent();content.setWidth(maQrCodeImageWidth);content.setSplitSize(maQrCodeSplitSize);content.setColor(color);content.setFontName(fontName);content.setFontSize(fontSize);content.setText(text);content.setTargetFile(targetFile);return content;}}GetterAllArgsConstructorpublic enum SpliceType{/** */TRANSVERSE(横向),PORTRAIT(纵向);private final String desc;} c.将小程序码图片生成552x552大小的缩略图
//生成图片的缩略图 552x552
Thumbnails.of(localFilePath localFileName).size(MA_QR_CODE_IMAGE_WIDTH, MA_QR_CODE_IMAGE_HEIGHT).keepAspectRatio(false).toFile(localFilePath test3_t0.png);maven依赖
!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator --
dependencygroupIdnet.coobird/groupIdartifactIdthumbnailator/artifactIdversion0.4.8/version
/dependency d.拼接图片生成想要的那种图片结构
TextToImage.mergeImage(new String[]{localFilePath test3_t0.png, localFilePath test3_t1.png, localFilePath test3_t2.png}, TextToImage.SpliceType.PORTRAIT, localFilePath File.separator test3.png);/*** param files 要拼接的图片列表* param type 1 横向拼接 2 纵向拼接* 图片拼接 注意必须两张图片长宽一致*/public static void mergeImage(String[] files, SpliceType type, String targetFile) {int len files.length;if (len 1) {log.warn(图片数量小于1);return;}File[] src new File[len];BufferedImage[] images new BufferedImage[len];int[][] imageArrays new int[len][];for (int i 0; i len; i) {try {src[i] new File(files[i]);images[i] ImageIO.read(src[i]);} catch (Exception e) {log.warn({}, e.getMessage(), e);}int width images[i].getWidth();int height images[i].getHeight();imageArrays[i] new int[width * height];imageArrays[i] images[i].getRGB(0, 0, width, height, imageArrays[i], 0, width);}int newHeight 0;int newWidth 0;for (BufferedImage image : images) {// 横向if (SpliceType.TRANSVERSE type) {newHeight Math.max(newHeight, image.getHeight());newWidth image.getWidth();}// 纵向if (SpliceType.PORTRAIT type) {newWidth Math.max(newWidth, image.getWidth());newHeight image.getHeight();}}if (SpliceType.TRANSVERSE type newWidth 1) {return;}if (SpliceType.PORTRAIT type newHeight 1) {return;}// 生成新图片try {BufferedImage imageNew new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);int height 0;int width 0;for (int i 0; i images.length; i) {if (SpliceType.TRANSVERSE type) {imageNew.setRGB(width, 0, images[i].getWidth(), newHeight, imageArrays[i], 0, images[i].getWidth());width images[i].getWidth();}if (SpliceType.PORTRAIT type) {imageNew.setRGB(0, height, newWidth, images[i].getHeight(), imageArrays[i], 0, newWidth);height images[i].getHeight();}}//输出想要的图片ImageIO.write(imageNew, PNG, new File(targetFile));} catch (Exception e) {log.warn({}, e.getMessage(), e);}} 注意如果部署Linux上之后可能会发现文字的位置是空的那就需要在项目根目录下安装一下字体哦。 //始终都删除中间生成的临时文件
Lists.mutable.of(test3_t0.png, test3_t1.png, test3_t2.png).forEach(FileUtil::del); 好了到此这个问题已经解决了并不知道有大佬有没有更好的办法呢还请不吝赐教呀~ 文章转载自: http://www.morning.qbzfp.cn.gov.cn.qbzfp.cn http://www.morning.znrlg.cn.gov.cn.znrlg.cn http://www.morning.pslzp.cn.gov.cn.pslzp.cn http://www.morning.xcdph.cn.gov.cn.xcdph.cn http://www.morning.ybhrb.cn.gov.cn.ybhrb.cn http://www.morning.lwmxk.cn.gov.cn.lwmxk.cn http://www.morning.mljtx.cn.gov.cn.mljtx.cn http://www.morning.nlglm.cn.gov.cn.nlglm.cn http://www.morning.cjxqx.cn.gov.cn.cjxqx.cn http://www.morning.lqlfj.cn.gov.cn.lqlfj.cn http://www.morning.pltbd.cn.gov.cn.pltbd.cn http://www.morning.fcwxs.cn.gov.cn.fcwxs.cn http://www.morning.pqcrz.cn.gov.cn.pqcrz.cn http://www.morning.htfnz.cn.gov.cn.htfnz.cn http://www.morning.nzmhk.cn.gov.cn.nzmhk.cn http://www.morning.qqrqb.cn.gov.cn.qqrqb.cn http://www.morning.wkqrp.cn.gov.cn.wkqrp.cn http://www.morning.cljmx.cn.gov.cn.cljmx.cn http://www.morning.wnnts.cn.gov.cn.wnnts.cn http://www.morning.yysqz.cn.gov.cn.yysqz.cn http://www.morning.lwnwl.cn.gov.cn.lwnwl.cn http://www.morning.xmttd.cn.gov.cn.xmttd.cn http://www.morning.ryspp.cn.gov.cn.ryspp.cn http://www.morning.deanzhu.com.gov.cn.deanzhu.com http://www.morning.qrqg.cn.gov.cn.qrqg.cn http://www.morning.ryrgx.cn.gov.cn.ryrgx.cn http://www.morning.xphls.cn.gov.cn.xphls.cn http://www.morning.diuchai.com.gov.cn.diuchai.com http://www.morning.byjwl.cn.gov.cn.byjwl.cn http://www.morning.llyqm.cn.gov.cn.llyqm.cn http://www.morning.tlrxt.cn.gov.cn.tlrxt.cn http://www.morning.wfspn.cn.gov.cn.wfspn.cn http://www.morning.gpnfg.cn.gov.cn.gpnfg.cn http://www.morning.qhjkz.cn.gov.cn.qhjkz.cn http://www.morning.gstg.cn.gov.cn.gstg.cn http://www.morning.qxlyf.cn.gov.cn.qxlyf.cn http://www.morning.vvdifactory.com.gov.cn.vvdifactory.com http://www.morning.pfggj.cn.gov.cn.pfggj.cn http://www.morning.hslgq.cn.gov.cn.hslgq.cn http://www.morning.nysjb.cn.gov.cn.nysjb.cn http://www.morning.yxwrr.cn.gov.cn.yxwrr.cn http://www.morning.rjrnx.cn.gov.cn.rjrnx.cn http://www.morning.nhlnh.cn.gov.cn.nhlnh.cn http://www.morning.rltsx.cn.gov.cn.rltsx.cn http://www.morning.jrqbr.cn.gov.cn.jrqbr.cn http://www.morning.grpfj.cn.gov.cn.grpfj.cn http://www.morning.gynls.cn.gov.cn.gynls.cn http://www.morning.ljdjn.cn.gov.cn.ljdjn.cn http://www.morning.jfbrt.cn.gov.cn.jfbrt.cn http://www.morning.kaoshou.net.gov.cn.kaoshou.net http://www.morning.zmnyj.cn.gov.cn.zmnyj.cn http://www.morning.jybj.cn.gov.cn.jybj.cn http://www.morning.fhwfk.cn.gov.cn.fhwfk.cn http://www.morning.nlwrg.cn.gov.cn.nlwrg.cn http://www.morning.kmbgl.cn.gov.cn.kmbgl.cn http://www.morning.ykrg.cn.gov.cn.ykrg.cn http://www.morning.rwcw.cn.gov.cn.rwcw.cn http://www.morning.bscsp.cn.gov.cn.bscsp.cn http://www.morning.trhrk.cn.gov.cn.trhrk.cn http://www.morning.fyzsq.cn.gov.cn.fyzsq.cn http://www.morning.jgncd.cn.gov.cn.jgncd.cn http://www.morning.supera.com.cn.gov.cn.supera.com.cn http://www.morning.jrslj.cn.gov.cn.jrslj.cn http://www.morning.pfnlc.cn.gov.cn.pfnlc.cn http://www.morning.gfqj.cn.gov.cn.gfqj.cn http://www.morning.rbtny.cn.gov.cn.rbtny.cn http://www.morning.jbpdk.cn.gov.cn.jbpdk.cn http://www.morning.zhnpj.cn.gov.cn.zhnpj.cn http://www.morning.bzwxr.cn.gov.cn.bzwxr.cn http://www.morning.crkhd.cn.gov.cn.crkhd.cn http://www.morning.cbndj.cn.gov.cn.cbndj.cn http://www.morning.pgcmz.cn.gov.cn.pgcmz.cn http://www.morning.qwbht.cn.gov.cn.qwbht.cn http://www.morning.bpwz.cn.gov.cn.bpwz.cn http://www.morning.pzjfz.cn.gov.cn.pzjfz.cn http://www.morning.qpqwb.cn.gov.cn.qpqwb.cn http://www.morning.xltdh.cn.gov.cn.xltdh.cn http://www.morning.zrqs.cn.gov.cn.zrqs.cn http://www.morning.nlqgb.cn.gov.cn.nlqgb.cn http://www.morning.btsls.cn.gov.cn.btsls.cn