圖片轉二進制(互轉)


Note:

圖片轉二進制數據只需轉化為bate數組二進制數據即可,例如要求httpclient發送圖片二進制數據即是把生成的bate數組數據發送過去。如果對方明確提出是字符串格式編碼,再進一步轉化就好了

 

使用Base64轉換圖片

利用Base64實現二進制和圖片之間的轉換,具體代碼如下:

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.tomcat.util.codec.binary.Base64;

public class ImageBinary {

    public static void main(String[] args) {
        String fileName = "D://code//test.jpg";
        System.out.println(getImageBinary(fileName));
        saveImage(getImageBinary(fileName));
    }

    /*
     * 圖片轉換為二進制
     * 
     * @param fileName
     *            本地圖片路徑
     * @return
     *       圖片二進制流
     * */
    public static String getImageBinary(String fileName) {
        File f = new File(fileName);
        BufferedImage bi;
        try {
            bi = ImageIO.read(f);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bi, "jpg", baos);
            byte[] bytes = baos.toByteArray();
            return Base64.encodeBase64String(bytes);
            //return encoder.encodeBuffer(bytes).trim();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 將二進制轉換為圖片
     * 
     * @param base64String
     *            圖片二進制流
     *       
     */
    public static void saveImage(String base64String) {
        try {
            byte[] bytes1 = Base64.decodeBase64(base64String);
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
            BufferedImage bi1 = ImageIO.read(bais);
            File w2 = new File("D://code//22.jpg");// 可以是jpg,png,gif格式
            ImageIO.write(bi1, "jpg", w2);// 不管輸出什么格式圖片,此處不需改動
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

網絡地址url與本地圖片獲取圖片字節流

    若通過url訪問圖片並轉換為二進制流,就不能按照上述方法。通過url獲取圖片涉及url、網絡狀態等各種情況。在代碼中涉及兩種不同的方法:一個是通過url的形式,另一個是直接訪問本地資源(即圖片路徑)。詳見以下代碼:

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class ImageUtil {

    /**
     * 根據地址獲得數據的字節流
     *
     * @param strUrl
     *            網絡連接地址
     * @return
     */
    public static byte[] getImageFromNetByUrl(String strUrl) {
        try {
            URL url = new URL(strUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5 * 1000);
            InputStream inStream = conn.getInputStream();// 通過輸入流獲取圖片數據
            byte[] btImg = readInputStream(inStream);// 得到圖片的二進制數據
            return btImg;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根據地址獲得數據的字節流
     *
     * @param strUrl
     *            本地連接地址
     * @return
     */
    public byte[] getImageFromLocalByUrl(String strUrl) {
        try {
            File imageFile = new File(strUrl);
            InputStream inStream = new FileInputStream(imageFile);
            byte[] btImg = readInputStream(inStream);// 得到圖片的二進制數據
            return btImg;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 從輸入流中獲取數據
     *
     * @param inStream
     *            輸入流
     * @return
     * @throws IOException
     * @throws Exception
     */
    private static byte[] readInputStream(InputStream inStream) throws IOException {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[10240];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        inStream.close();
        return outStream.toByteArray();

    }
    
    public static void main(String[] args) {
        String url = "https://images0.cnblogs.com/blog/536814/201412/051633343733092.png";
        byte[] b = getImageFromNetByUrl(url);
        System.out.println(b);
    }
}

url獲取圖片字節流

   本節介紹的方法可以說是前兩種方法的結合體,但是在兩者的基礎上有所優化,如對url的狀態做判斷,此方法僅供參考,可根據具體需求做相應調整。

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import javax.imageio.ImageIO;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

public class ImageUtils {

    /*
     * 獲取原圖片二進制流
     * 
     * @param imageUrl
     *             原圖片地址
     * */
    public static String getImageBinary(String imageUrl) {
        String data = null;
        try {
            int HttpResult = 0; // 服務器返回的狀態
            URL url = new URL(imageUrl); // 創建URL
            URLConnection urlconn = url.openConnection(); // 試圖連接並取得返回狀態碼
            urlconn.connect();
            HttpURLConnection httpconn = (HttpURLConnection) urlconn;
            HttpResult = httpconn.getResponseCode();
            if (HttpResult != HttpURLConnection.HTTP_OK) // 不等於HTTP_OK則連接不成功
                System.out.print("failed");
            else {
                BufferedInputStream bis = new BufferedInputStream(urlconn.getInputStream());
                BufferedImage bm = ImageIO.read(bis);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                String type = imageUrl.substring(imageUrl.length() - 3);
                ImageIO.write(bm, type, bos);
                bos.flush();
                data = Base64.encode(bos.toByteArray());
                bos.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;

    }

    public static void main(String[] args) {
        String url = "https://images0.cnblogs.com/blog/536814/201412/051633343733092.png";
        String result = getImageBinary(url);
        System.out.println(result);
    }
}

url獲取圖片字節流

 本方法實現了主要實現了以下幾個功能:

   1、通過url將圖片轉換為字節流(十六進制的形式),並實現字節流與圖片之間的相互轉換;

   2、將本地圖片轉換為字節流(十六進制的形式),並實現字節流與圖片之間的相互轉換;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import javax.imageio.ImageIO;

public class Utils {
    /**
     * 圖片轉換成二進制字符串
     * 
     * @param imageUrl
     *            圖片url
     * @return String 二進制流
     */
    public static String getImgeHexStringByUrl(String imageUrl) {
        String res = null;
        try {
            int HttpResult = 0; // 服務器返回的狀態
            URL url = new URL(imageUrl); // 創建URL
            URLConnection urlconn = url.openConnection(); // 試圖連接並取得返回狀態碼
            urlconn.connect();
            HttpURLConnection httpconn = (HttpURLConnection) urlconn;
            HttpResult = httpconn.getResponseCode();
            if (HttpResult != HttpURLConnection.HTTP_OK) // 不等於HTTP_OK則連接不成功
                System.out.print("failed");
            else {
                BufferedInputStream bis = new BufferedInputStream(urlconn.getInputStream());
                BufferedImage bm = ImageIO.read(bis);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                String type = imageUrl.substring(imageUrl.length() - 3);
                ImageIO.write(bm, type, bos);
                bos.flush();
                byte[] data = bos.toByteArray();
                res = byte2hex(data);
                bos.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    /**
     * 本地圖片轉換成二進制字符串
     * 
     * @param imageUrl
     *            圖片url
     * @return String 二進制流
     */
    public static String getImgeHexStringByLocalUrl(String imageUrl) {
        String res = null;

        try {
            File imageFile = new File(imageUrl);
            InputStream inStream = new FileInputStream(imageFile);
            BufferedInputStream bis = new BufferedInputStream(inStream);
            BufferedImage bm = ImageIO.read(bis);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            String type = imageUrl.substring(imageUrl.length() - 3);
            ImageIO.write(bm, type, bos);
            bos.flush();
            byte[] data = bos.toByteArray();
            res = byte2hex(data);
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    /**
     * @title 根據二進制字符串生成圖片
     * @param data
     *            生成圖片的二進制字符串
     * @param fileName
     *            圖片名稱(完整路徑)
     * @param type
     *            圖片類型
     * @return
     */
    public static void saveImage(String data, String fileName, String type) {

        BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_BYTE_BINARY);
        ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, type, byteOutputStream);
            // byte[] date = byteOutputStream.toByteArray();
            byte[] bytes = hex2byte(data);
            RandomAccessFile file = new RandomAccessFile(fileName, "rw");
            file.write(bytes);
            file.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 反格式化byte
     * 
     * @param s
     * @return
     */
    public static byte[] hex2byte(String s) {
        byte[] src = s.toLowerCase().getBytes();
        byte[] ret = new byte[src.length / 2];
        for (int i = 0; i < src.length; i += 2) {
            byte hi = src[i];
            byte low = src[i + 1];
            hi = (byte) ((hi >= 'a' && hi <= 'f') ? 0x0a + (hi - 'a') : hi - '0');
            low = (byte) ((low >= 'a' && low <= 'f') ? 0x0a + (low - 'a') : low - '0');
            ret[i / 2] = (byte) (hi << 4 | low);
        }
        return ret;
    }

    /**
     * 格式化byte
     * 
     * @param b
     * @return
     */
    public static String byte2hex(byte[] b) {
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] out = new char[b.length * 2];
        for (int i = 0; i < b.length; i++) {
            byte c = b[i];
            out[i * 2] = Digit[(c >>> 4) & 0X0F];
            out[i * 2 + 1] = Digit[c & 0X0F];
        }

        return new String(out);
    }

    public static void main(String[] args) {
        String fileName = "D://code//cc.png";
        String url = "https://images0.cnblogs.com/blog/536814/201412/051633343733092.png";
        String outImage = "D://code//11.png";
        /*
         * url形式
         * */
        String result = getImgeHexStringByUrl(url);
        System.out.println(result);
        saveImage(result,fileName,"png");
        /*
         * 本地圖片形式
         * */
        String result1 = getImgeHexStringByLocalUrl(fileName);
        System.out.println(result1);
        saveImage(result1,outImage,"png");
    }

}

通過url下載圖片

   在給定url的情況下,可將url所訪問的圖片下載至本地。具體代碼如下:

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

public class downimageUtil {

    private static final String filePath = "C://Users//lizhihui//Desktop//";

    /*
     * 根據url下載圖片
     * 
     * @param  destUrl
     *             url連接
     * @return 
     *       圖片保存路徑
     * */
    public String saveToFile(String destUrl) {
        String fileName = "";
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        HttpURLConnection httpUrl = null;
        URL url = null;
        int BUFFER_SIZE = 1024;
        byte[] buf = new byte[BUFFER_SIZE];
        int size = 0;
        try {
            url = new URL(destUrl);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            bis = new BufferedInputStream(httpUrl.getInputStream());
            for (String string : destUrl.split("/")) {
                if (string.contains("png") || string.contains("png") || string.contains("gif")) {
                    fileName = string;
                }
            }
            fos = new FileOutputStream(filePath + fileName);
            while ((size = bis.read(buf)) != -1) {
                fos.write(buf, 0, size);
            }
            fos.flush();
        } catch (IOException e) {
        } catch (ClassCastException e) {
        } finally {
            try {
                fos.close();
                bis.close();
                httpUrl.disconnect();
            } catch (IOException e) {
            } catch (NullPointerException e) {
            }
        }
        return filePath + fileName;
    }
    
    public static void main(String[] args) {
        downimageUtil dw = new downimageUtil();
        String url = "https://images0.cnblogs.com/blog/536814/201412/051633343733092.png";
        System.out.println(dw.saveToFile(url));
    }
}

根據圖片網絡地址獲取二進制與二進制轉圖片親測實例:

/**
     * 根據圖片地址獲得數據的字節流
     *
     * @param strUrl
     * @return
     */
    public static byte[] getImageFromNetByUrl(String strUrl) {
        try {
            URL url = new URL(strUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5 * 1000);
            InputStream inStream = conn.getInputStream();// 通過輸入流獲取圖片數據
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, len);
            }
            byte[] btImg = outStream.toByteArray();// 得到圖片的二進制數據
            
            inStream.close();
            outStream.close();
            conn.disconnect();
            return btImg;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }    
    
    
    //byte數組到圖片
    public static void byte2image(byte[] data,String path){
      if(data.length<3||path.equals("")) return;
      try{
      FileImageOutputStream imageOutput = new FileImageOutputStream(new File(path));
      imageOutput.write(data, 0, data.length);
      imageOutput.close();
      System.out.println("Make Picture success,Please find image in " + path);
      } catch(Exception ex) {
        System.out.println("Exception: " + ex);
        ex.printStackTrace();
      }
    }

 

到此,對於圖片的處理結束,這是在寫圖片壓縮服務器時所用到的部分技術,當然在此基本上有所改進,在此不再一一列舉,對於圖片的壓縮方法后續也會整理出來,歡迎查看!雖然寫出來了,但還沒進行壓力測試,優化等一系列后續工作。就先這樣吧......

 

本文摘寫自:https://blog.csdn.net/hh12211221/article/details/74639049

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM