2011-01-29 50 views
33

Tôi biết điều này có thể đã được hỏi 10000 lần, tuy nhiên, dường như tôi không thể tìm ra câu trả lời thẳng cho câu hỏi.Chuyển đổi byte [] thành chuỗi Base64 cho dữ liệu URI

Tôi có LOB được lưu trữ trong db của tôi đại diện cho hình ảnh; Tôi nhận được hình ảnh đó từ DB và tôi muốn hiển thị nó trên một trang web thông qua thẻ HTML IMG. Đây không phải là giải pháp ưa thích của tôi, nhưng đó là một triển khai khoảng trống cho đến khi tôi có thể tìm ra giải pháp tốt hơn.

Tôi đang cố gắng để chuyển đổi các byte [] để Base64 sử dụng Apache Commons Codec theo cách sau:

String base64String = Base64.encodeBase64String({my byte[]}); 

Sau đó, tôi đang cố gắng để hiển thị hình ảnh của tôi trên trang của mình như thế này:

<img src="data:image/jpg;base64,{base64String from above}"/> 

Hiển thị hình ảnh mặc định của trình duyệt "Tôi không thể tìm thấy hình ảnh này".

Có ai có ý tưởng nào không?

Cảm ơn.

+0

bạn có thể post đoạn code đầy đủ ... tôi cần nó để tham khảo. ..i cũng có cùng một vấn đề ... nhưng tôi không có bất kỳ ý tưởng về cách mã sẽ được .. – Lucky

Trả lời

38

tôi đã sử dụng này và nó làm việc tốt (trái với các câu trả lời được chấp nhận, trong đó sử dụng một định dạng không được khuyến khích cho kịch bản này):

StringBuilder sb = new StringBuilder(); 
sb.append("data:image/png;base64,"); 
sb.append(StringUtils.newStringUtf8(Base64.encodeBase64(imageByteArray, false))); 
contourChart = sb.toString(); 
+2

đây là câu trả lời đúng, không có mã hóa UTF8, trình duyệt sẽ cung cấp cho bạn tất cả các cơn đau đầu ngắn. – phamductri

+1

bạn đã sử dụng nhập khẩu nào? – kozla13

+0

IIRC, lớp Base64 là một từ commache apache, mặc dù tôi không thực sự chắc chắn nữa (và không còn có quyền truy cập vào dự án đó). – WhyNotHugo

12

Theo tài liệu chính thức, Base64.encodeBase64URLSafeString(byte[] binaryData) phải là những gì bạn đang tìm kiếm.

Ngoài ra loại mime cho JPG là image/jpeg.

+1

[Ví dụ PNG trên bài viết trên Wikipedia] (https://secure.wikimedia.org/wikipedia/en/ wiki/Data_URI_scheme # Ví dụ) gợi ý rằng việc sử dụng + và/là ổn. –

+1

Có ai thực sự đã thử sử dụng đầu ra của Base64.encodeBase64URLSafeString() để xem nó có hoạt động trong trình duyệt không? encodeBase64URLSafeString() dường như không tạo mã hóa base64 hợp lệ/chuẩn. Để thực hiện tuân thủ URI chuỗi được mã hóa base64, bạn nên áp dụng ký tự thoát URI chuẩn cho nó. Tôi không nghĩ rằng các chức năng trên là những gì bạn muốn. – Keeth

+0

Câu trả lời này không thực sự tạo ra chuỗi thích hợp cho tôi. Câu trả lời từ Hugo chứa mã hóa bị thiếu để làm cho nó hoạt động. – ryber

2

Bạn cũng có thể muốn xem xét truyền trực tuyến hình ảnh ra trình duyệt thay vì mã hóa chúng trên chính trang đó.

Dưới đây là một ví dụ về truyền một hình ảnh chứa trong một tập tin ra cho trình duyệt thông qua một servlet, mà có thể dễ dàng được thông qua để dòng nội dung của BLOB của bạn, chứ không phải là một tập tin:

public void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException 
    { 
    ServletOutputStream sos = resp.getOutputStream(); 
    try { 
     final String someImageName = req.getParameter(someKey); 

     // encode the image path and write the resulting path to the response 
     File imgFile = new File(someImageName); 

     writeResponse(resp, sos, imgFile); 
    } 
    catch (URISyntaxException e) { 
     throw new ServletException(e); 
    } 
    finally { 
     sos.close(); 
    } 
    } 

    private void writeResponse(HttpServletResponse resp, OutputStream out, File file) 
    throws URISyntaxException, FileNotFoundException, IOException 
    { 
    // Get the MIME type of the file 
    String mimeType = getServletContext().getMimeType(file.getAbsolutePath()); 
    if (mimeType == null) { 
     log.warn("Could not get MIME type of file: " + file.getAbsolutePath()); 
     resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
     return; 
    } 

    resp.setContentType(mimeType); 
    resp.setContentLength((int)file.length()); 

    writeToFile(out, file); 
    } 

    private void writeToFile(OutputStream out, File file) 
    throws FileNotFoundException, IOException 
    { 
    final int BUF_SIZE = 8192; 

    // write the contents of the file to the output stream 
    FileInputStream in = new FileInputStream(file); 
    try { 
     byte[] buf = new byte[BUF_SIZE]; 
     for (int count = 0; (count = in.read(buf)) >= 0;) { 
     out.write(buf, 0, count); 
     } 
    } 
    finally { 
     in.close(); 
    } 
    } 
+0

Tôi đang sử dụng Spring Web MVC và toàn bộ trang đang được xây dựng bằng cách sử dụng gạch, v.v. Tôi thực sự không muốn đi qua PITA tạo bộ điều khiển khác và gọi từng hình ảnh riêng biệt, nhưng cảm ơn! –

1

Nếu bạn không muốn truyền từ một servlet, sau đó lưu tệp vào một thư mục trong webroot và sau đó tạo src trỏ đến vị trí đó. Bằng cách đó, máy chủ web thực hiện công việc phục vụ tệp. Nếu bạn cảm thấy đặc biệt thông minh, bạn có thể kiểm tra một tập tin hiện có bằng dấu thời gian/inode/crc32 và chỉ ghi nó ra nếu nó đã thay đổi trong DB mà có thể cung cấp cho bạn một tăng hiệu suất. Phương pháp tệp này cũng sẽ tự động hỗ trợ ETag và nếu được sửa đổi kể từ tiêu đề để trình duyệt có thể lưu trữ tệp đúng cách.

Các vấn đề liên quan