工作中遇到通過圖片的url獲取圖片base64位的需求。一開始是用網上的方法,通過工具類Toolkit,雖然實現的代碼比較簡短,不過偶爾會遇到圖片轉成base64位不正確的情況,至今不知道為啥。
之后,又去網上搜了通過獲取圖片的二進制流轉換成base64的方式,兩種方式,都是親測有效,通過Toolkit偶爾會出現,轉base64后,展示不完整的問題。所以建議用通過下載二進制流轉換的方式進行轉換。
下面附上代碼:
import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; import java.awt.Image; import java.awt.Toolkit; import java.awt.Transparency; import java.net.HttpURLConnection; import java.net.URL; public class ImageUtils { public static String getBase64ByImgUrl(String url){ String suffix = url.substring(url.lastIndexOf(".") + 1); try { URL urls = new URL(url); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Image image = Toolkit.getDefaultToolkit().getImage(urls); BufferedImage biOut = toBufferedImage(image); ImageIO.write(biOut, suffix, baos); String base64Str = Base64Util.encode(baos.toByteArray()); return base64Str; } catch (Exception e) { return ""; } } public static BufferedImage toBufferedImage(Image image) { if (image instanceof BufferedImage) { return (BufferedImage) image; } // This code ensures that all the pixels in the image are loaded image = new ImageIcon(image).getImage(); BufferedImage bimage = null; GraphicsEnvironment ge = GraphicsEnvironment .getLocalGraphicsEnvironment(); try { int transparency = Transparency.OPAQUE; GraphicsDevice gs = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gs.getDefaultConfiguration(); bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency); } catch (HeadlessException e) { // The system does not have a screen } if (bimage == null) { // Create a buffered image using the default color model int type = BufferedImage.TYPE_INT_RGB; bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type); } // Copy image to buffered image Graphics g = bimage.createGraphics(); // Paint the image onto the buffered image g.drawImage(image, 0, 0, null); g.dispose(); return bimage; } /** * 通過圖片的url獲取圖片的base64字符串 * @param imgUrl 圖片url * @return 返回圖片base64的字符串 */ public static String image2Base64(String imgUrl) { URL url = null; InputStream is = null; ByteArrayOutputStream outStream = null; HttpURLConnection httpUrl = null; try{ url = new URL(imgUrl); httpUrl = (HttpURLConnection) url.openConnection(); httpUrl.connect(); httpUrl.getInputStream(); is = httpUrl.getInputStream(); outStream = new ByteArrayOutputStream(); //創建一個Buffer字符串 byte[] buffer = new byte[1024]; //每次讀取的字符串長度,如果為-1,代表全部讀取完畢 int len = 0; //使用一個輸入流從buffer里把數據讀取出來 while( (len=is.read(buffer)) != -1 ){ //用輸出流往buffer里寫入數據,中間參數代表從哪個位置開始讀,len代表讀取的長度 outStream.write(buffer, 0, len); } // 對字節數組Base64編碼 return Base64Util.encode(outStream.toByteArray()); }catch (Exception e) { e.printStackTrace(); } finally{ if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if(outStream != null) { try { outStream.close(); } catch (IOException e) { e.printStackTrace(); } } if(httpUrl != null) { httpUrl.disconnect(); } } return imgUrl; } }
其中
getBase64ByImgUrl方法為通過Toolkit獲取的方式,至於為啥沒注釋,因為我也看不懂原理,也是抄來的。
image2Base64方法為通過下載二進制流的方式,當然也是抄來的。寫出來是為了總結一下。下次遇到相同的問題,不用到處查了。
附上Base64Util的代碼:
1 import java.io.ByteArrayOutputStream; 2 import java.io.File; 3 import java.io.IOException; 4 import java.util.regex.Matcher; 5 import java.util.regex.Pattern; 6 7 import javax.imageio.stream.FileImageInputStream; 8 9 import sun.misc.BASE64Decoder; 10 import sun.misc.BASE64Encoder; 11 12 public class Base64Util{ 13 /** 14 * 字符串轉圖片 15 * @param base64Str 16 * @return 17 */ 18 public static byte[] decode(String base64Str){ 19 byte[] b = null; 20 BASE64Decoder decoder = new BASE64Decoder(); 21 try { 22 b = decoder.decodeBuffer(replaceEnter(base64Str)); 23 } catch (IOException e) { 24 e.printStackTrace(); 25 } 26 return b; 27 } 28 29 /** 30 * 圖片轉字符串 31 * @param image 32 * @return 33 */ 34 public static String encode(byte[] image){ 35 BASE64Encoder decoder = new BASE64Encoder(); 36 return replaceEnter(decoder.encode(image)); 37 } 38 39 public static String encode(String uri){ 40 BASE64Encoder encoder = new BASE64Encoder(); 41 return replaceEnter(encoder.encode(uri.getBytes())); 42 } 43 44 /** 45 * 46 * @path 圖片路徑 47 * @return 48 */ 49 50 public static byte[] imageTobyte(String path){ 51 byte[] data = null; 52 FileImageInputStream input = null; 53 try { 54 input = new FileImageInputStream(new File(path)); 55 ByteArrayOutputStream output = new ByteArrayOutputStream(); 56 byte[] buf = new byte[1024]; 57 int numBytesRead = 0; 58 while((numBytesRead = input.read(buf)) != -1){ 59 output.write(buf, 0, numBytesRead); 60 } 61 data = output.toByteArray(); 62 output.close(); 63 input.close(); 64 65 } catch (Exception e) { 66 e.printStackTrace(); 67 } 68 69 return data; 70 } 71 72 73 74 public static String replaceEnter(String str){ 75 String reg ="[\n-\r]"; 76 Pattern p = Pattern.compile(reg); 77 Matcher m = p.matcher(str); 78 return m.replaceAll(""); 79 } 80 81 82 }