Czy istnieje sposób na ustawienie obrazu tła jako obrazu zakodowanego w standardzie Base64?

91

Chcę dynamicznie zmieniać tło w JS, a mój zestaw obrazów jest zakodowany w formacie base64. Próbuję:

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

z doskonałym wynikiem,

jednak nie robię tego samego z:

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

ani

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

Czy jest na to sposób?

Igor Savinkin
źródło
url('powinno działać, mój problem polegał na tym, że adres URL dataURL ActionScript faktycznie zawierał znaki nowej linii i musiałemreplace(/\n/g, '')
neaumusic

Odpowiedzi:

97

Próbowałem zrobić to samo co ty, ale najwyraźniej backgroundImage nie działa z zakodowanymi danymi. Jako alternatywę sugeruję użycie klas CSS i zmianę między tymi klasami.

Jeśli generujesz dane „w locie”, możesz dynamicznie ładować pliki CSS.

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;

Bawiłem się tutaj, wcisnąłem przycisk, a to zmieni tła div: http://jsfiddle.net/egorbatik/fFQC6/

Ezequiel Gorbatik
źródło
dziękuję, ale pracuję z dużą ilością elementów, więc wymiana zajęć nie jest praktyczna.
Igor Savinkin
1
@IgorSavinkin i ktokolwiek to przeczyta w przyszłości. Jeśli jednocześnie zmieniasz wiele elementów na to samo tło, możesz użyć css do kaskadowego renderowania, umieszczając klasę dla każdego elementu, który chcesz zmienić, ale zmieniając klasę wspólnego elementu nadrzędnego. Na przykład css to #ancestor.backgroundA .Change{background-image:...}i #ancestor.backgroundB .Change{background-image...}, gdzie #ancestorjest identyfikatorem wspólnego przodka i .Changejest klasą stosowaną do wszystkich elementów, do których należy zastosować jedno z teł.
Patanjali
Zabawne jest widzieć, jak wszyscy głosują na tę odpowiedź jako najlepszą, zanim nawet pomyślą, czy dobrą praktyką byłoby utworzenie CSS z milionem klas ... lub nawet lepiej: CSS zawierającego milion obrazów zakodowanych w base64 folder z milionem obrazów w jakości HD). Ale tak, to działa w przypadku kilku obrazów.
gabriel garcia
Ponadto, jak rozwiązałbyś problem dodawania nowych obrazów do dostępnych w systemie obrazów? czy to podejście jest w ogóle skalowalne?
gabriel garcia
35

Miałem ten sam problem z base64. Dla każdego w przyszłości z tym samym problemem:

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

Działałoby to z konsoli, ale nie w skrypcie:

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

Ale po trochę zabawie wpadłem na to:

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

Nie mam pojęcia, dlaczego działa z obrazem proxy, ale tak. Testowane na Firefox Dev 37 i Chrome 40.

Mam nadzieję, że to komuś pomoże.

EDYTOWAĆ

Zbadane trochę dalej. Wygląda na to, że czasami kodowanie base64 (przynajmniej w moim przypadku) zrywa z CSS ze względu na podziały wierszy obecne w zakodowanej wartości (w moim przypadku wartość była generowana dynamicznie przez ActionScript).

Po prostu używając np:

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

działa też, a nawet wydaje się być szybszy o kilka ms niż przy użyciu obrazu proxy.

lutogniew
źródło
2
Usunięcie przerw w linii naprawiło to za mnie.
Evan,
Dobre śledztwo.
Sølve Tornøe
31

Spróbuj tego, otrzymałem odpowiedź sukcesu ... to działa

$("#divId").css("background-image", "url('data:image/png;base64," + base64String + "')");
gihansalith
źródło
Wydaje się, że jeśli data:image/png;base64jest długi, a łańcuch definiuje się jako zmienna jquery, to nie działa. Ale działa, jeśli ciąg zdefiniowany jako zmienna php, jak przykład PHClaus .... Tylko informacje o tym, co testowałem
Andris,
13

Dodanie tej sztuczki do następującego rozwiązania Gabriela Garcii -

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

Jednak w moim przypadku to nie działało. Przeniesienie adresu URL do zmiennej img załatwiło sprawę. Więc ostateczny kod wyglądał tak

var img = "url('data:image/png;base64, "+base64Data + "')";
document.body.style.backgroundImage = img; 
Amit Kumar Rai
źródło
1
@Amit Kumar Rai masz rację. Brakowało mi pojedynczych cudzysłowów w moim kodzie, który faktycznie napisałeś, więc twój kod działa.
gabriel garcia
8

Próbowałem tego (i pracowałem dla mnie):

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

Składnia ES6:

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

Trochę lepiej:

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

let node = nodeIGotFromDOM, img = imageBase64EncodedFromMyGF;
setBackground.call(node, img);
gabriel garcia
źródło
1
Zabawne, ponieważ jest to dokładnie ten kod, który mówią ludzie, nie działa.
Pimp Trizkit
U mnie to też działa. Testowane również na Microsoft Edge i IE 11
Ryan.C
2

Zwykle najpierw zapisuję pełny ciąg w zmiennej, na przykład:

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

Następnie, gdy chcę, aby JS zrobił coś z tą zmienną:

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

Możesz odwołać się do tej samej zmiennej bezpośrednio przez PHP, używając czegoś takiego jak:

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

Pracuje dla mnie ;)


źródło
2

To jest właściwy sposób na wykonanie czystej rozmowy. Brak CSS.

<div style='background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAFCAYAAABW1IzHAAAAHklEQVQokWNgGPaAkZHxPyMj439sYrSQo51PBgsAALa0ECF30JSdAAAAAElFTkSuQmCC)repeat-x center;'></div>
user5641497
źródło
<div style = 'background: url (data: image / png; base64, iVBORw0KGgoAAAANSUhEUgAAABwAAAAFCAYAAABW1IzHAAAAHklEQVQokWNgGPaAkZHxPyMj439sYrSQo51PBgsAALa0ECF30JSdAAAAAElFTkSuQmCC) Centrum repeat-x;'> </ div>
user5641497
Aby wysłać kod, wsuń go czterema spacjami lub zaznacz go i naciśnij Ctrl-K.
2

Myślę, że to pomoże, Base64 jest adresowany przez CSS w inny sposób, powinieneś ustawić typ danych obrazu na base64, to pomoże CSS zmienić base64 na obraz i wyświetlić go użytkownikowi. i możesz użyć tego z javascript, przypisując obraz tła za pomocą skryptu jquery, automatycznie zmieni on base64 na maga i wyświetli go

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
źródło
Odpowiedzi zawierające tylko kod są odradzane. Kliknij edytuj i dodaj kilka słów podsumowujących, w jaki sposób Twój kod odpowiada na pytanie, lub może wyjaśnij, w jaki sposób Twoja odpowiedź różni się od poprzedniej odpowiedzi / odpowiedzi. Nie widzę żadnej rzeczywistej różnicy między tą a jedną z wcześniej opublikowanych odpowiedzi.
Nick
0

W moim przypadku to tylko dlatego, że nie ustawiłem heighti width.

Ale jest inny problem.

Obraz tła można usunąć za pomocą

element.style.backgroundImage=""

ale nie można go ustawić za pomocą

element.style.backgroundImage="some base64 data"

Jquery działa dobrze.

stlebeax
źródło