工作中遇到通过图片的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 }