2011-01-29 22 views
33

Sé que esto se ha pedido probablemente 10000 veces, sin embargo, parece que no puedo encontrar una respuesta directa a la pregunta.Convierta byte [] a cadena Base64 para URI de datos

Tengo un LOB almacenado en mi db que representa una imagen; Obtengo esa imagen de la base de datos y me gustaría mostrarla en una página web a través de la etiqueta HTML IMG. Esta no es mi solución preferida, pero es una implementación temporal hasta que pueda encontrar una mejor solución.

Estoy tratando de convertir el byte [] para utilizar la base 64 Apache Commons Codec de la siguiente manera:

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

Entonces, yo estoy tratando de mostrar mi imagen en mi página de la siguiente manera:

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

Muestra la imagen predeterminada del navegador "No puedo encontrar esta imagen".

¿Alguien tiene alguna idea?

Gracias.

+0

Se puede publicar el código completo ... lo necesito para referencia. ... también tengo el mismo problema ... pero no tengo idea de cómo será el código ... – Lucky

Respuesta

38

He utilizado este y funcionó bien (al contrario de la respuesta aceptada, que utiliza un formato no recomendada para este escenario):

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

esta es la respuesta correcta, sin la codificación UTF8, el navegador le dará todo menos dolores de cabeza. – phamductri

+1

¿qué importaciones usaste? – kozla13

+0

IIRC, la clase Base64 es la de apache commons, aunque ya no estoy seguro (y ya no tengo acceso a ese proyecto). – WhyNotHugo

12

De acuerdo con la documentación oficial Base64.encodeBase64URLSafeString(byte[] binaryData) debería ser lo que estás buscando.

También el tipo de mime para JPG es image/jpeg.

+1

El [ejemplo PNG en el artículo de Wikipedia] (https://secure.wikimedia.org/wikipedia/en/ wiki/Data_URI_scheme # Examples) sugiere que usar + y/está bien. –

+1

¿Alguien ha intentado realmente usar la salida de Base64.encodeBase64URLSafeString() para ver si funciona en un navegador? encodeBase64URLSafeString() no parece generar codificación base64 válida/estándar. Para hacer que una cadena codificada en base64 sea compatible con URI, debe aplicarle el carácter URI estándar que escapa. No creo que la función anterior sea lo que quieres. – Keeth

+0

Esta respuesta en realidad no generó la cadena adecuada para mí. La respuesta de Hugo contiene la codificación faltante para que funcione. – ryber

2

Quizás también desee considerar la transmisión de las imágenes al navegador en lugar de codificarlas en la página.

He aquí un ejemplo de la transmisión de una imagen contenida en un archivo de salida al navegador por medio de un servlet, que podría ser fácilmente adoptada para transmitir el contenido de su BLOB, en lugar de un archivo:

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

Estoy usando Spring Web MVC y toda la página está siendo construida usando tiles, etc ... Realmente no quiero pasar por el PITA de crear otro controlador y llamar cada imagen por separado, ¡pero gracias! –

1

Si no desea transmitir desde un servlet, luego guarde el archivo en un directorio en la raíz web y luego cree el src que apunta a esa ubicación. De esa forma, el servidor web hace el trabajo de servir el archivo. Si te sientes especialmente inteligente, puedes buscar un archivo existente por timestamp/inode/crc32 y solo escribirlo si ha cambiado en la base de datos, lo que puede darte un impulso en el rendimiento. Este método de archivo también admitirá automáticamente los encabezados ETag y if-modified-since para que el navegador pueda almacenar en caché el archivo correctamente.

Cuestiones relacionadas