图片处理:html文本获取图片Url,判断图片大小,存数据库

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);

    }

}