¿Hay alguna manera de configurar la imagen de fondo como una imagen codificada en base64?

84

Quiero cambiar el fondo de forma dinámica en JS y mi conjunto de imágenes está codificado en base64. Lo intento:

document.getElementById("bg_image").style.backgroundImage = 
   "url('http://amigo.com/300107-2853.jpg')"; 

con resultado perfecto,

sin embargo, no hago lo mismo con:

document.getElementById("bg_image").style.backgroundImage = 
   "url('data:image/png;base64,iVBORw0KGgoAAAAAAAAyCAYAAAAUYybjAAAgAElE...')";

ni

document.getElementById("bg_image").style.backgroundImage = 
   "data:image/png;base64,iVBORw0KGgoAAAAAAAAyCAYAAAAUYybjAAAgAElE...";

¿Hay alguna forma de hacerlo?

Igor Savinkin
fuente
url('debería funcionar, mi problema era que la URL de datos de ActionScript en realidad tenía nuevas líneas, y tuve que hacerloreplace(/\n/g, '')
neaumusic

Respuestas:

91

Intenté hacer lo mismo que tú, pero aparentemente backgroundImage no funciona con datos codificados. Como alternativa, sugiero usar clases CSS y el cambio entre esas clases.

Si está generando los datos "sobre la marcha", puede cargar los archivos CSS de forma dinámica.

CSS:

.backgroundA {
    background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDUxRjY0ODgyQTkxMTFFMjk0RkU5NjI5MEVDQTI2QzUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDUxRjY0ODkyQTkxMTFFMjk0RkU5NjI5MEVDQTI2QzUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpENTFGNjQ4NjJBOTExMUUyOTRGRTk2MjkwRUNBMjZDNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpENTFGNjQ4NzJBOTExMUUyOTRGRTk2MjkwRUNBMjZDNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuT868wAAABESURBVHja7M4xEQAwDAOxuPw5uwi6ZeigB/CntJ2lkmytznwZFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYW1qsrwABYuwNkimqm3gAAAABJRU5ErkJggg==");
}

.backgroundB {
    background-image:url("data:image/gif;base64,R0lGODlhUAAPAKIAAAsLav///88PD9WqsYmApmZmZtZfYmdakyH5BAQUAP8ALAAAAABQAA8AAAPbWLrc/jDKSVe4OOvNu/9gqARDSRBHegyGMahqO4R0bQcjIQ8E4BMCQc930JluyGRmdAAcdiigMLVrApTYWy5FKM1IQe+Mp+L4rphz+qIOBAUYeCY4p2tGrJZeH9y79mZsawFoaIRxF3JyiYxuHiMGb5KTkpFvZj4ZbYeCiXaOiKBwnxh4fnt9e3ktgZyHhrChinONs3cFAShFF2JhvCZlG5uchYNun5eedRxMAF15XEFRXgZWWdciuM8GCmdSQ84lLQfY5R14wDB5Lyon4ubwS7jx9NcV9/j5+g4JADs=");
}

HTML:

<div id="test" height="20px" class="backgroundA"> 
  div test 1
</div>
<div id="test2" name="test2" height="20px" class="backgroundB">
  div test2
</div>
<input type="button" id="btn" />

Javascript:

function change() {
    if (document.getElementById("test").className =="backgroundA") {
        document.getElementById("test").className="backgroundB";
        document.getElementById("test2").className="backgroundA";
    } else {
        document.getElementById("test").className="backgroundA";
        document.getElementById("test2").className="backgroundB";
    }
}

btn.onclick= change;

Lo manipulé aquí, presioné el botón y cambiará los fondos de los divs: http://jsfiddle.net/egorbatik/fFQC6/

Ezequiel Gorbatik
fuente
gracias, pero trabajo con gran cantidad de elementos, por lo que no es práctico intercambiar clases.
Igor Savinkin
1
@IgorSavinkin y quien lea esto en el futuro. Si está cambiando muchos elementos al mismo fondo simultáneamente, puede usar css para poner en cascada la representación, colocando una clase contra cada elemento que desea cambiar, pero cambiando la clase de un elemento ancestro común. Por ejemplo, el CSS sería #ancestor.backgroundA .Change{background-image:...}y #ancestor.backgroundB .Change{background-image...}, donde #ancestores el id del ancestro común, y .Changees la clase aplicada a todos los elementos a los que se aplica uno de los fondos.
Patanjali
Es gracioso ver a todos votando esta respuesta como la mejor antes incluso de pensar si sería una buena práctica crear un CSS con un millón de clases ... o incluso mejor: un CSS que contenga un millón de imágenes codificadas en base64 (consejo: solo piensa en una carpeta con un millón de imágenes en HD, tal vez). Pero sí, esto funciona para algunas imágenes.
gabriel garcia
Además, ¿cómo resolvería el problema de agregar nuevas imágenes a las imágenes disponibles en su sistema? ¿Es este enfoque incluso escalable?
gabriel garcia
32

Tuve el mismo problema con base64. Para cualquier persona en el futuro con el mismo problema:

url = "data:image/png;base64,iVBORw0KGgoAAAAAAAAyCAYAAAAUYybjAAAgAElE...";

Esto funcionaría ejecutado desde la consola, pero no desde dentro de un script:

$img.css("background-image", "url('" + url + "')");

Pero después de jugar un poco con él, se me ocurrió esto:

var img = new Image();
img.src = url;
$img.css("background-image", "url('" + img.src + "')");

No tengo idea de por qué funciona con una imagen proxy, pero lo hace. Probado en Firefox Dev 37 y Chrome 40.

Espero que ayude a alguien.

EDITAR

Investigé un poco más. Parece que a veces la codificación base64 (al menos en mi caso) se rompe con CSS debido a los saltos de línea presentes en el valor codificado (en mi caso, el valor fue generado dinámicamente por ActionScript).

Simplemente usando, por ejemplo:

$img.css("background-image", "url('" + url.replace(/(\r\n|\n|\r)/gm, "") + "')");

también funciona, e incluso parece ser más rápido en unos pocos ms que usar una imagen proxy.

Lutogniew
fuente
2
Quitar los saltos de línea lo arregló para mí.
Evan
Buena investigacion.
Sølve Tornøe
31

Pruebe esto, tengo una respuesta de éxito ... está funcionando

$("#divId").css("background-image", "url('data:image/png;base64," + base64String + "')");
Gihansalith
fuente
Parece que si data:image/png;base64es largo y la cadena se define como variable jquery, entonces no funciona. Pero funciona si la cadena se define como una variable php como el ejemplo de PHClaus ... Solo información sobre lo que probé
Andris
12

Añadiendo este truco a la siguiente solución de gabriel garcía:

var img = 'data:image/png;base64, ...'; //place ur base64 encoded img here
document.body.style.backgroundImage = 'url(' + img + ')';

Sin embargo, en mi caso, esto no funcionó. Mover la URL a la variable img funcionó. ASÍ que el código final se veía así

var img = "url('data:image/png;base64, "+base64Data + "')";
document.body.style.backgroundImage = img; 
Amit Kumar Rai
fuente
1
@Amit Kumar Rai, tienes razón. Me faltaban las comillas simples en mi código, que usted realmente escribió para que su código funcione.
Gabriel García
7

Probé esto (y funcionó para mí):

var img = 'data:image/png;base64, ...'; //place ur base64 encoded img here
document.body.style.backgroundImage = 'url(\'' + img + '\')';

Sintaxis de ES6:

let img = 'data:image/png;base64, ...'
document.body.style.backgroundImage = ´url('${img}'

Un poco mejor:

let setBackground = src=>{
    this.style.backgroundImage = `url('${src}')`
}

let node = nodeIGotFromDOM, img = imageBase64EncodedFromMyGF
setBackground.call(node, img)
gabriel garcia
fuente
1
Es curioso, porque este es exactamente el código que la gente dice que no funciona.
Pimp Trizkit
Esto también funciona para mí. Probado en Microsoft Edge e IE 11 también
Ryan.C
2

Lo que suelo hacer es almacenar primero la cadena completa en una variable, así:

<?php
$img_id = 'data:image/png;base64,iVBORw0KGgoAAAAAAAAyCAY...';
?>

Entonces, donde quiero que JS haga algo con esa variable:

<script type="text/javascript">
document.getElementById("img_id").backgroundImage="url('<?php echo $img_id; ?>')";
</script>

Puede hacer referencia a la misma variable a través de PHP directamente usando algo como:

<img src="<?php echo $img_id; ?>">

Funciona para mi ;)


fuente
2

Ésta es la forma correcta de realizar una llamada pura. Sin CSS.

<div style='background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAFCAYAAABW1IzHAAAAHklEQVQokWNgGPaAkZHxPyMj439sYrSQo51PBgsAALa0ECF30JSdAAAAAElFTkSuQmCC)repeat-x center;'></div>
usuario5641497
fuente
<div style = 'background: url (datos: image / png; base64, iVBORw0KGgoAAAANSUhEUgAAABwAAAAFCAYAAABW1IzHAAAAHklEQVQokWNgGPaAkZHxPyMj439sYrSQo51PBgsAALa0ECF30JSdAAAAAElFTkSuQmCC) Centro de repetición-x;'> </ div>
user5641497
Para publicar código, sangra con cuatro espacios o selecciónalo y presiona Ctrl-K.
2

Creo que esto ayudará, CSS aborda Base64 de una manera diferente, debe establecer el tipo de datos de la imagen en base64, esto ayudará a CSS a cambiar la base64 a imagen y mostrársela al usuario. y puede usar esto desde javascript asignando la imagen de fondo usando el script jquery, automáticamente cambiará el base64 a mage y lo mostrará

url = "data:image;base64,"+data.replace(/(\r\n|\n|\r)/gm, "");
$("body").css("background-image", "url('" + url.replace(/(\r\n|\n|\r)/gm, "") + "')");

Rami Mohammed
fuente
Se desaconsejan las respuestas de solo código. Haga clic en editar y agregue algunas palabras que resuman cómo su código aborda la pregunta, o quizás explique en qué se diferencia su respuesta de la respuesta / respuestas anteriores. No veo ninguna diferencia real entre esto y una de las respuestas publicadas anteriormente.
Nick
0

En mi caso, fue solo porque no configuré el heighty width.

Pero hay otro problema.

La imagen de fondo se puede eliminar usando

element.style.backgroundImage=""

pero no se pudo configurar usando

element.style.backgroundImage="some base64 data"

Jquery funciona bien.

stlebeax
fuente