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