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 id="queryPic" resultMap="picMap" parameterType="java.util.Map"> 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 id="picMap" type="Bean.PicVO"> <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); } }