Java生成并合并图片以及base64转图片
由于最近研究了下打码平台(验证码识别平台),但是像需要特殊说明的验证码(例如:只需要提取验证码中黄颜色的字符),就需要将说明
信息和验证码图片合成一张图片,然后在发送给打码平台才可以。所以,我就研究了下使用Java操作图片。
因为我获取到的验证码图片信息是经过base64编码的字符串,所以我需要先进行解码。其次因为我只需要提取特定颜色的信息,所以我
还要将具体信息和验证码进行图片合成。
下面就来看一下我写的DEMO:
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;import javax.imageio.ImageIO;import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;public class ImageOperation {public static final String diskPath = "E:/TEMP/IMAGE/"; // 图片临时文件路径public static final Map<String, Color> colorMap = new HashMap<String,Color>();public static final Map<String, String> tipsMap = new HashMap<String,String>();static{colorMap.put("00", Color.BLACK);colorMap.put("01", Color.RED);colorMap.put("02", Color.YELLOW);colorMap.put("03", Color.BLUE);tipsMap.put("00", "选择验证码");tipsMap.put("01", "选择红色验证码");tipsMap.put("02", "选择黄色验证码");tipsMap.put("03", "选择蓝色验证码");}public static void main(String[] args) throws Exception {long startTime = System.nanoTime();createFolder(diskPath);String imageBase64 = "iVBORw0KGgoAAAANSUhEUgAAAFoAAAAjCAIAAACb54pcAAAKXUlEQVR42tVaCThUexs/yRJjX0t81pS0pw2pq2QJhYjbQijVVcgnUW5SIVIUkYomynap3CJR6VqzRJFJEbcSZcluhNx3nLmHxhgzsnzf8/yf87zn/e+/83t/7/+cGYRYUEZPETVcjhpPXBro7DIppSmT/We6I+O0rPQLfzBUYubrM9plPMrYwHFM8BFc5U7YjgKISSlnWKeNIxyjY8SIJWIK3/8lOyZ40dtuOI7haHaqTAzAscczbqjTdI34mKOQFRz+M92bN7fRqN208uUYsCMdH+NksXcC6FD7Sq2biOvpYq+vWJYbGkxR+3xO5yQHi/+R49NwODZWVgRB5srM+nkgONi6l8vXJnolgG0hcYyi9kP+ZpQg7zJ2Ai6dTSLZl/ETsP8bPPgR4Ag7dZadbRoPJxcYcJsXlQCIVCVnUB2uyN4jzzUg8+xN2rOyMPeaaRD4uIgI0rdbp4Sitvj271lBEYM9r5Nt+/qQl3Huo95n4X+92mZKEvkEO4Rm/K1lnHsimGF2EBJSRQQEBXj5IvGhqOdd0l/i00Wn8wtL9JD0pvDOHYr+MGXJvqNwbRcRa5RflH/UP8sngqKNgmSDuWYpap/dlz6NtZuiQePfi1CjukibkOhA3k+0FyCSERjFKBAFzue+cfF0s3O832Dw/IgvlE8qGl08/BUG5gzAYaqtx8LMjD/ti3k2LFMFXuzV2z5c52wvfNmOA9itvq46LAWggQdSu+IX1HnaOh3gwNpwcXRRwAEBUhTjAUZGQDTsH0pvDwvq+fRSozLrVxJ99rvCgEOBHlpKLR37EKR8iyXY8GyAvEATWBVcibwCtPvuCiwcgMPZav8x6wOoOvjud2ViYpolJvXAewS1bxP9T8lel1y3IJyD4mA/zF23eNU9Twi0vjS/ONS5cWUl3B43e4bS5JBRIRggFmhtVbZpe4N4xVMLknY0C4MnDx9I9BbsZWH9Kje/VVy6i5u30NGbxmIgIgCLlwfdX++07WFjf7XHGVCA0jRLAfxVOqYMsKMttxS48NQ/FrwifIISImLmmkaACO3+5Ua7gZYwGRRYQeW/VOrkF67SNpEQaXEyzUc9eOeH0MpG/wXYKEzuu3LEhFrrqxagDQhJ9gBHc/Wcrjb+F3+cJD3qe4eJSwVRUgDiaFTSWAxExFvjPW9NrGEx9fOXATp5xwOfnboCLCaY29OrHXHlh9AbQ1Vt03WbwDBR02OeOtVgtab/ATfAZcRRQE3hGTZLz0FvXx5wg+iN3B/NgyNibcA2WF2OKav3XpI2Q05VWlb4wPsu1WG/904t32uFxQgQ5LWZHeBCnRpuQTBppm8kYAExMvpEi9088o0Egjw+T1avhz4RsjMlwRPu4kd7FCACFNT+vHwNShagBkQE6jxlmS3E24Ha86TqTdeRJy3NVYe25P2EDewzDx/Q2836rYOHpCAqGlgWyz92AYSJ6hqq126EcKjU/RV4Mdj/wu4U9Mo4H8UwHFD0lNSBI6T3haP+AAQLM8v1I760hvCPbZaaXdCPF4hILzMLGjXgAQpgzabzt0cfTwJDdUG1vARZWVPO3i4qWijC106SvXD/j4U6BRF+lZnbAYuSu0dBU3OuhELVlyXKGX7RWCKDfJFFTdGgCkjaIiELwjmg0z4RABNELqyqU0AE8z8OjKQLDpQgcAX7soOnjb4ZDSwgKL4orkbtMjFZlBTRa9n7x7mNPvbA85xwBWo4mhRIizbh2L9h3ZcuIOjo/IkyqKZYva1OsumjAmhHS60s5JT0iyQVk7DgzPEIfa+xhUwBVW141FjKhNBonLsYpU+g9h5IJaC1WGMoLZJymf17gZMRgJJ62sMpdd+qyqW8HdxUEUGGHjQ1l6/ZuFINjCB7DxpZFlAv/u13dCbQfADiOxNTkYPnYLF46HMHI8JCmTpMO6BsVqmIj9e33JaE3gIXKE5ig0v7DHHUyDl9FRBBBRUSRzcHrtTqcIPCUpAVYBDarGGeYo2SOigoAAENwJNma+50Z9PatCmcRA61N0puSfbJw7wf/QCHVuRqVDKAIA/7BSz+ZEio09mBUHobihpwzkMZa3bfHnIqaBhkXMIuBwgcTFBdtudhpy+K4mD8HLhT/GY2dxd75XNd4EVLjRzt0wTkCCyFQ4oBVsIayMcfzzBIHCClcP2wnnTYrzC0gCdUsoT74D0N+RoZwTpky6NZV91V8z7VMqYdGEHWLVHuz47nUKYMDVSUhBQ6AhhBqGOnA8XZn7etf03RzFC1HLCAFBuWZbrqOxOxVeBLmfLQ17YfXvAOxbf+m/KBDqDWEEFYLWRWUCuIC9IpRt8sVwm3L2GldN1MoVZ+o9y1KRpsxbsd6M0sO4KzsZtbelyDFQQ9g4F8pAx5JekQFoXDLzwxWBZZtP1jwXh2MgTiBSRtkDa/Y2PpmS3eCMEiNaO5X176fln8Aaosc7Zuy9+ceelmUYzniAuFQx2Mn/DbOswDzwMCByIURuxlQtJVENM8renNwjId4o5RUjlquO9TkD5Orm7Ho4x9K6U6vYWWsfI8RQVJORw7B9XTFyqcQwucICmyGhy6TNTeABYgpfD+hr7UkqT0/XzvBJcswzSqC7DcKj/4FlQDJsVoCEDAXN9YkOQNiHUwMr2eZUGLrOung/mlfw5sL7d0NJ+OyYTUPUOxoEt2p1y221i0CQ13HgV+gobBtUlmLjIcPMOUtIBoji72B8E36KTxm6uh7f0HQjj4tnMg8frI9nCEvwFZ9YrXs9yWUJIafiltFN/xYuR76GIHQ4VT6yujXS7HeMrWSTLUJfPIsXBzZoM4hKcJWZ+CBOCVq/Ifje0PAGMAh9+Okb/TxDXYUHj2Z+w0LNKmZ/y7V6/yXNNWb1bh7uHUK56Ft2Kr22VE5/ZY9dPhqmlNHA0cWxuzxvBD0yKOGTRqld8puifSEvzY65e8PzgrtS7l6+He2qhzq+JCvdeT8f7Vigo7WPPFGNp23McURpH660IsdycnPHZSblt4/fFqTawqPMLPKttkcbuCULfArjqju2+vePt8Gds9WxJ2jj5Y7qtXjfkXSvzNc2Jff+DOlagzO/IM5DqlxLtEbT7vTC2L6CggUF3xwoYTE8qOCSiHnuzWebXu6cWYi3HuW4q0hVsFZ3dKH66xziTETe5PvOMOh65zE4XncWDUoo9zF1bPhfcouS/SbtV2Ra8S6Vkr26r7w1XF7rah3fdWjC5qdOJaJhSOnroffhNxeSZBfosLunky0WF9mQonEcfSwywcpfimmLo0apnugWvQo3iqtS2HSieNHcnH5/0kOvdDrruk2Ki8W4brYl9RtdjxsXVItJfoNxGGVvkw5ElNxbnJDxZBAyv6d95o7Y/Zt6+FgEDAMRzXxbGmfIVrsi16AE3YmHilytO4ceP/wp9BmJLCxjdYovABcL6aVyMHeVSDsMbj3uHUS7fIL+bk+T6b1RteeO823BLtbl2cMDhMii0Yg+NaOT+didMix1imToK/nXdz8QbfO65PAqIHfmQYNN+H2jBZokRCp8cEE8GnwonCc3ga89Bm/wCHa/l8eRGk8QAAAABJRU5ErkJggg==";String yzmImagePath = encode64Image(imageBase64);String tipsImagePath = generateImageTips(tipsMap.get("01"),colorMap.get("01"));String composeImagePath = composeImage(tipsImagePath, yzmImagePath);deleteFile(new String[]{yzmImagePath,tipsImagePath});System.out.println("共消耗"+((System.nanoTime()-startTime)/1000000000)+"秒");}// 生成文件路径public static boolean createFolder(String folderPath){if(StringUtils.isBlank(folderPath)){return false;}File file = new File(folderPath);if(!file.exists()){file.mkdirs();}return true;}// 解码base64图片,并保存public static String encode64Image(String imageBase64){if(StringUtils.isBlank(imageBase64)){return null;}String fileName = getRandomString(15);byte[] decode = Base64.decodeBase64(imageBase64);int length = decode.length;for(int i=0;i<length;++i){if(decode[i] < 0){decode[i] += 256;}}OutputStream out = null;try {out = new FileOutputStream(new File(diskPath+fileName));try {out.write(decode);out.flush();} catch (IOException e) {e.printStackTrace();}} catch (FileNotFoundException e) {e.printStackTrace();}finally{try {out.close();} catch (IOException e) {e.printStackTrace();}}return diskPath+fileName;}// 生成提示文字图片public static String generateImageTips(String tips,Color color) throws Exception{int width = 90; int height = 35; String fileName = getRandomString(15);File file = new File(diskPath+fileName); Font font = new Font("Serif", Font.BOLD, 10); BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = (Graphics2D)bi.getGraphics(); g2.setBackground(Color.WHITE); g2.clearRect(0, 0, width, height); g2.setPaint(color); FontRenderContext context = g2.getFontRenderContext(); Rectangle2D bounds = font.getStringBounds(tips, context);double x = (width - bounds.getWidth()) / 2; double y = (height - bounds.getHeight()) / 2; double ascent = -bounds.getY(); double baseY = y + ascent; g2.drawString(tips, (int)x, (int)baseY); ImageIO.write(bi, "png", file); return diskPath+fileName;}// 合成图片public static String composeImage(String img1Path,String img2Path){try { //第一张图片 File fileOne = new File(img1Path); BufferedImage imageOne = ImageIO.read(fileOne); int width = imageOne.getWidth(); int height = imageOne.getHeight(); int[] imageArrayOne = new int[width*height]; imageArrayOne = imageOne.getRGB(0,0,width,height,imageArrayOne,0,width); //第二张图片 File fileTwo = new File(img2Path); BufferedImage imageTwo = ImageIO.read(fileTwo); int width2 = imageTwo.getWidth(); int height2 = imageTwo.getHeight(); int[] ImageArrayTwo = new int[width2*height2]; ImageArrayTwo = imageTwo.getRGB(0,0,width,height,ImageArrayTwo,0,width); //新图片 BufferedImage imageNew = new BufferedImage(width,height*2,BufferedImage.TYPE_INT_RGB); imageNew.setRGB(0,0,width,height,imageArrayOne,0,width); imageNew.setRGB(0,height,width,height,ImageArrayTwo,0,width);String fileName = getRandomString(15);File outFile = new File(diskPath+fileName+".png"); ImageIO.write(imageNew, "png", outFile);return diskPath+fileName+".png";} catch (Exception e) { e.printStackTrace(); } return null;}// 删除无用的图片public static boolean deleteFile(String[] paths){if(paths == null || paths.length == 0){return false;}File file = null;for(String p:paths){file = new File(p);file.deleteOnExit();}return true;}// 生成图片临时文件名public static String getRandomString(int length) { //length表示生成字符串的长度String base = "abcdefghijklmnopqrstuvwxyz0123456789";Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); } }
上述代码可直接使用。
Java生成并合并图片以及base64转图片相关推荐
- uni-app 多端本地图片转base64 本地图片转base64
文章目录 uni 适配多端 本地图片转base64 函数 多端转换统一函数 使用 h5本地图片转base64 app本地图片转base64 微信小程序本地图片转base64 uni 适配多端 本地图片 ...
- opencv读写和保存中文路径图片及base64与图片互转
文章目录 1.opencv读取中文路径图片 2.opencv保存中文路径图片 3.图片转base64 4.base64转图片 有几点要注意 cv2.imread(filename,flags) cv2 ...
- java生成二维码,中间插入图片,以及二维码解析
在实际的项目中有用到生成二维码的功能,生成的二维码中间可以插入一张图片. 先来效果图 (这是我事先准备了一张图片 a)---- 生成的二维码的效果图 (二维码中间插入的图片就是上面保存的图片a) 好了 ...
- java 生成柱状图、饼状图等图片保存至word文档
写在前面,springboot pom 中引入下面就可以了,省了在csdn找包很麻烦. <dependency><artifactId>jfreechart</artif ...
- mysql base64 图片php_php base64转图片
1.解析base64数据成图片 The problem is that data:image/bmp;base64, is included in the encoded contents. This ...
- Java实现图片和Base64之间的相互转化
目录 一.简介 二.maven依赖 三.工具类 四.测试 一.简介 工作中调用第三方接口的时候,比如(人脸识别,身份证识别,文字识别等等)有时是图片,有时是Base64的字符串,一般前端上传的都是 ...
- vue 前端生成二维码,并转换为图片
这篇文章主要是分享下自己的收获,也是自己遇到的问题: 前端如何自己生成二维码? 前端如何将生成的二维码转成图片并展示? 如何控制二维码的显隐? 话不多说,直接上干货 base64如何转换成图片 npm ...
- python 图片解密:base64
引言 小编在在一些批量下载图片的爬虫程序的过程中,发现了一种被base64加密的图片,今天一个京东案例带大家彻底掌握base64加密破解,建议大家先看视频再去研究代码,思路才是最重要的. base64 ...
- BASE64转换为图片格式,并上传图片
基本的把base64 转成图片 # 将BASE64转换为图片格式## 代码```javapublic static final String JPG = ".jpg";public ...
最新文章
- 自学python数据分析要多久-数据分析培训班要学习多长时间?
- 【错误记录】Android 应用运行报错 ( java.lang.VerifyError: Verifier rejected class androidx. | 逆向中遇到的问题 )
- 智能家居 (3) ——智能家居工厂模式介绍实现继电器控制灯
- mysql获取离当前数据最近的数据_Mysql 获取最近数据信息
- fiddler如何filter_Fiddler工具的过滤功能介绍
- php 文件服务器,GitHub - RainmanJin/PSFS: PHP Simple File Server 极简版PHP文件服务器
- Consumer clientId=consumer-1, groupId=console-consumer-950] Connection to node -1 could not be
- 23_使用dtree展示所有分类
- 2010计算机操作员中级试题,计算机操作员中级操作技能考核试卷(一)
- TalkingData游戏统计对接
- highcharts特殊定制:x轴文字竖直显示(兼容各浏览器)
- 哈密顿算子在直角坐标系的矩阵表示
- PHP Class SoapClient not found解决方法
- HTTP协议个人总结
- golang内幕之for-go-statement
- 【数据结构实验】二叉树的创建与功能实现
- C语言输出菱形图案(二维数组)
- PMP考试英文报名申请中项目经验该怎样填写?
- dpt rp1维修 sony_你们的sony dpt rp1有变弯和开裂的现象么?
- c语言从键盘输入asdfg输出asdfg,西南财经大学2009级C语言程序设计期末试题.pdf