1.从html文本获取图片Url
/** * html文本中取出url链接 */ public class Url { public static void main(String[] args) { String content="<div><img src='123.jpg'/>ufiolk<img src='456.jpg'/></div>"; List<String> imgUrls = parseImg(content); for (String imgUrl : imgUrls) { System.out.println(imgUrl); } } public static List<String> parseImg(String content){ Element doc = Jsoup.parseBodyFragment(content).body(); Elements elements = doc.select("img[src]"); List<String> imgUrls = new ArrayList<>(elements == null ? 1 : elements.size()); for (Element element : elements) { String imgUrl = element.attr("src"); if(StringUtils.isNotBlank(imgUrl)){ imgUrls.add(imgUrl); } } return imgUrls; } }
2.判断图片大小,格式
public class Url { public static void main(String[] args) { boolean b = checkImageSize(new File("C:\\Users\\吕厚厚\\Pictures\\Warframe\\wallhaven-760559 (1).png"), 1 * 1024L); System.out.println(b); } /** * 校验图片的大小 * @param file 文件 * @param imageSize 图片最大值(KB) * @return true:上传图片小于图片的最大值 */ public static boolean checkImageSize(File file, Long imageSize) { if (!file.exists()) { return false; } System.out.println("file.length:"+ file.length()); Long size = file.length() / 1024; // 图片大小(得到的是字节数,需除以1024,转化为KB) System.out.println("size:"+size); Long maxImageSize = null; if (maxImageSize == null) { maxImageSize = 2 * 1024L;// 图片最大不能超过2M(2048kb) } else { maxImageSize = maxImageSize * 1024; } if (size > maxImageSize) { return false; } if (imageSize == null) { return true; } if (size.intValue() <= imageSize) { return true; } return false; } //根据文件名判断图片是否为要求的格式 public static boolean checkImageType(String fileFullname){ //获取图片扩展名 String type = fileFullname.substring(fileFullname.lastIndexOf(".") + 1); //判断是否为要求的格式 if (type == "bmp" || type == "jpg" || type == "jpeg" || type == "gif" || type == "JPG" || type == "JPEG" || type == "BMP" || type == "GIF") { return true; } return false; } }
根据流判断图片类型
//测试根据文件流判断图片类型 @Test public void judgeImageType(){ PicVO pic = weixinReleaseMaterialDao.getPic("a00394c9-4db4-43c6-adc7-d7d3019624ed"); if(pic==null||pic.getBinaryPic()==null){ throw new RuntimeException("从数据库取出二进制数据的字节数组为空"); } byte[] binaryPic =pic.getBinaryPic(); String picType = getPicType(binaryPic); System.out.println("pic____"+picType); } /** * 根据文件流判断图片类型 * @param * @return jpg/png/gif/bmp */ public static String getPicType(byte[] src) { StringBuilder stringBuilder = new StringBuilder(); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < 4; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } String type = stringBuilder.toString().toUpperCase(); if (type.contains("FFD8FF")) { return IMG_JPG; } else if (type.contains("89504E47")) { return IMG_PNG; } else if (type.contains("47494638")) { return IMG_GIF; } else if (type.contains("424D")) { return IMG_BMP; }else{ return ""; } }
3. 根据URL下载图片
public class Url { public static void main(String[] args) { /*String content="<div><img src='123.jpg'/>ufiolk<img src='456.jpg'/></div>"; List<String> imgUrls = parseImg(content); for (String imgUrl : imgUrls) { System.out.println(imgUrl); }*/ /*boolean b = checkImageSize(new File("C:\\Users\\吕厚厚\\Pictures\\Warframe\\wallhaven-760559 (1).png"), 1 * 1024L); System.out.println(b);*/ //根据url下载图片 String imgUrl="https://pics4.baidu.com/feed/a8014c086e061d950b35770c91eacad462d9cab3.jpeg?token=c41d6d4d1b4c59af07a9bfc2b874b245&s=702A955598FECFCC341BFCEF0300E038"; InputStream inputStream = downloadImgByUrl(imgUrl); try { byte[] s = IOUtils.toByteArray(inputStream);//byte数组接收 System.out.println(s); } catch (IOException e) { e.printStackTrace(); } } public static InputStream downloadImgByUrl(String imageUrl) { InputStream inputStream = null; inputStream = ImgUtils.getByUrl(imageUrl);//通过url下载并得到输入流 if (null == inputStream) { throw new RuntimeException("下载文件出错,输入流为空"); } return inputStream; }
3.存图片到数据库
数据类型选择:
BLOB类型的字段用于存储二进制数据
MySQL中,BLOB是个类型系列,包括:TinyBlob、Blob、MediumBlob、LongBlob,这几个类型之间的唯一区别是在存储文件的最大大小上不同。
MySQL的四种BLOB类型
类型 大小(单位:字节)
TinyBlob 最大 255
Blob 最大 65K
MediumBlob 最大 16M
LongBlob 最大 4G
从数据库查出图片:
直接查出表里的整个对象,避免byte[] 不知道对应的resultType的问题。
/**Mybatis3.0 *Dao层 * @param picId * @return */ public PicVO getPic(String picId){ Map<String, Object> param = new HashMap<>(); param.put("picId", picId); return super.selectOne(apperNameSpace .concat("queryPic"),param); } <!--查询二进制图片--> <select > select ID ,PIC_ID ,BINARY_PIC from zycf_mediaoperate_pics where 1=1 <if test="picId!=null"> and PIC_ID=#{picId,jdbcType=VARCHAR} </if> </select> <resultMap > <result column="ID" jdbcType="VARCHAR" property="id"/> <result column="PIC_ID" jdbcType="VARCHAR" property="picId"/> <result column="BINARY_PIC" property="binaryPic" jdbcType="LONGVARBINARY" /> </resultMap>
4.形成图片文件
//根据图片id从数据库取出二进制数据 String[] split = StringUtils.split(articlePicsId,","); if(split==null||split.length==0){ //throw new RuntimeException("split__为空"); } for (int i = 0; i <split.length ; i++) { PicVO pic = weixinReleaseMaterialDao.getPic(split[i]); if(pic==null||pic.getBinaryPic()==null){ //throw new RuntimeException("从数据库取出二进制数据的字节数组为空"); } byte[] binaryPic =pic.getBinaryPic(); //转为图片文件 File image = getImage(binaryPic); //字节数组转为图片文件 private static File getImage(byte[] bytes){ try { String tmpRootPath; String tmp = System.getProperty("java.io.tmpdir"); if(tmp.endsWith(File.separator)){ tmpRootPath = tmp; }else{ tmpRootPath = tmp.concat(File.separator); } ByteArrayInputStream bais = new ByteArrayInputStream(bytes); File jpgfile = new File(tmpRootPath.concat("123.jpg")); FileUtils.copyInputStreamToFile(bais, jpgfile); /* BufferedImage bi1 = ImageIO.read(bais); //String tempPath = PropertiesUtil.getProperty("trs-config.properties","mailTempDir"); // 文件名 File w2 = new File("C:\\Users\\吕厚厚\\Pictures\\Warframe", "123.jpg");// 可以是jpg,png,gif格式 ImageIO.write(bi1, "jpg", w2);// 不管输出什么格式图片,此处不需改动 */ return jpgfile; } catch (IOException e) { e.getMessage(); e.printStackTrace(); } return null; }
5.图片上传
//利用HttpPostUtil HttpPostUtil u = new HttpPostUtil(requestUrl); u.addFileParameter("img", new File(filePath)); //发送数据到服务器,解析返回数据 JSONObject result = JSONObject.parseObject(new String(u.send()));
HttpPostUtil:
import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class HttpPostUtil { URL url; HttpURLConnection conn; String boundary = "--------httppost123"; Map<String, String> textParams = new HashMap<String, String>(); Map<String, File> fileparams = new HashMap<String, File>(); DataOutputStream ds; public HttpPostUtil(String url) throws Exception { this.url = new URL(url); } //重新设置要请求的服务器地址,即上传文件的地址。 public void setUrl(String url) throws Exception { this.url = new URL(url); } //增加一个普通字符串数据到form表单数据中 public void addTextParameter(String name, String value) { textParams.put(name, value); } //增加一个文件到form表单数据中 public void addFileParameter(String name, File value) { fileparams.put(name, value); } // 发送数据到服务器,返回一个字节包含服务器的返回结果的数组 public byte[] send() throws Exception { initConnection(); try { conn.connect(); } catch (SocketTimeoutException e) { // something throw new RuntimeException(); } ds = new DataOutputStream(conn.getOutputStream()); writeFileParams(); writeStringParams(); paramsEnd(); InputStream in = conn.getInputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream(); int b; while ((b = in.read()) != -1) { out.write(b); } conn.disconnect(); return out.toByteArray(); } //文件上传的connection的一些必须设置 private void initConnection() throws Exception { conn = (HttpURLConnection) this.url.openConnection(); conn.setDoOutput(true); conn.setUseCaches(false); conn.setConnectTimeout(10000); //连接超时为10秒 conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); } //普通字符串数据 private void writeStringParams() throws Exception { Set<String> keySet = textParams.keySet(); for (Iterator<String> it = keySet.iterator(); it.hasNext();) { String name = it.next(); String value = textParams.get(name); ds.writeBytes("--" + boundary + "\r\n"); ds.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"\r\n"); ds.writeBytes("\r\n"); ds.writeBytes(encode(value) + "\r\n"); } } //文件数据 private void writeFileParams() throws Exception { Set<String> keySet = fileparams.keySet(); for (Iterator<String> it = keySet.iterator(); it.hasNext();) { //update-begin-author:taoYan date:20180601 for:文件加入http请求,当文件非本地资源的时候需要作特殊处理-- String name = it.next(); File value = fileparams.get(name); String valuename = value.getName(); if(value.exists()){ ds.writeBytes("--" + boundary + "\r\n"); ds.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + encode(valuename) + "\"\r\n"); ds.writeBytes("Content-Type: " + getContentType(value) + "\r\n"); ds.writeBytes("\r\n"); ds.write(getBytes(value)); }else{ String myFilePath = value.getPath(); if(myFilePath!=null && myFilePath.startsWith("http")){ byte[] netFileBytes = getURIFileBytes(myFilePath); String lowerValueName = valuename.toLowerCase(); if(lowerValueName.endsWith(IMG_BMP)||lowerValueName.endsWith(IMG_GIF)||lowerValueName.endsWith(IMG_JPG)||lowerValueName.endsWith(IMG_PNG)){ valuename = encode(valuename); }else{ valuename = System.currentTimeMillis()+getPicType(netFileBytes); } ds.writeBytes("--" + boundary + "\r\n"); ds.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + valuename + "\"\r\n"); ds.writeBytes("Content-Type: " + getContentType(value) + "\r\n"); ds.writeBytes("\r\n"); ds.write(netFileBytes); } } //update-end-author:taoYan date:20180601 for:文件加入http请求,当文件非本地资源的时候需要作特殊处理-- ds.writeBytes("\r\n"); } } /** * 通过文件的网络地址转化成流再读到字节数组中去 */ private byte[] getURIFileBytes(String url) throws IOException{ url = url.replace("http:"+File.separator,"http://").replace("\\","/"); URL oracle = new URL(url); InputStream inStream = oracle.openStream(); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } inStream.close(); return outStream.toByteArray(); } //获取文件的上传类型,图片格式为image/png,image/jpg等。非图片为application/octet-stream private String getContentType(File f) throws Exception { // return "application/octet-stream"; // 此行不再细分是否为图片,全部作为application/octet-stream 类型 ImageInputStream imagein = ImageIO.createImageInputStream(f); if (imagein == null) { return "application/octet-stream"; } Iterator<ImageReader> it = ImageIO.getImageReaders(imagein); if (!it.hasNext()) { imagein.close(); return "application/octet-stream"; } imagein.close(); return "image/" + it.next().getFormatName().toLowerCase();//将FormatName返回的值转换成小写,默认为大写 } //把文件转换成字节数组 private byte[] getBytes(File f) throws Exception { FileInputStream in = new FileInputStream(f); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int n; while ((n = in.read(b)) != -1) { out.write(b, 0, n); } in.close(); return out.toByteArray(); } //添加结尾数据 private void paramsEnd() throws Exception { ds.writeBytes("--" + boundary + "--" + "\r\n"); ds.writeBytes("\r\n"); } // 对包含中文的字符串进行转码,此为UTF-8。服务器那边要进行一次解码 private String encode(String value) throws Exception{ return URLEncoder.encode(value, "UTF-8"); } //update-begin-author:taoYan date:20180601 for:增加图片类型常量-- public static final String IMG_JPG = ".jpg"; public static final String IMG_PNG = ".png"; public static final String IMG_GIF = ".gif"; public static final String IMG_BMP = ".bmp"; /** * 根据文件流判断图片类型 * @param * @return jpg/png/gif/bmp */ public String getPicType(byte[] src) { StringBuilder stringBuilder = new StringBuilder(); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < 4; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } String type = stringBuilder.toString().toUpperCase(); if (type.contains("FFD8FF")) { return IMG_JPG; } else if (type.contains("89504E47")) { return IMG_PNG; } else if (type.contains("47494638")) { return IMG_GIF; } else if (type.contains("424D")) { return IMG_BMP; }else{ return ""; } } //update-end-author:taoYan date:20180601 for:根据文件流判断图片类型-- public static void main(String[] args) throws Exception { HttpPostUtil u = new HttpPostUtil("https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=i3um002Np_n-mgNVbPP9JEIfft7_hRq3eHE86slxI7Uh_5q0K5rFfLRnhD20HTCcFt92ulWnndpGlyiNgXi6UiWQqKxPCBsfYKmiY6Ws-isUVLaAFAXYO"); u.addFileParameter("img", new File("C:/Users/zhangdaihao/Desktop/2.png")); byte[] b = u.send(); String result = new String(b); System.out.println(result); } }