Есть ли способ установить фоновое изображение как изображение в кодировке base64?

91

Я хочу динамически изменять фон в JS, и мой набор изображений закодирован в base64. Я пытаюсь:

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

с отличным результатом,

но я не могу сделать то же самое с:

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

ни

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

Есть ли способ это сделать?

Игорь Савинкин
источник
url('должно работать, моя проблема заключалась в том, что в URL-адресе данных ActionScript действительно были символы новой строки, и мне пришлосьreplace(/\n/g, '')
neaumusic

Ответы:

97

Я пытался сделать то же самое, что и вы, но, видимо, backgroundImage не работает с закодированными данными. В качестве альтернативы я предлагаю использовать классы CSS и переключение между этими классами.

Если вы генерируете данные «на лету», вы можете загружать файлы 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;

Я поиграл здесь, нажмите кнопку, и он переключит фон div : http://jsfiddle.net/egorbatik/fFQC6/

Эсекьель Горбатик
источник
спасибо, но я работаю с большим количеством элементов, поэтому обмениваться классами нецелесообразно.
Игорь Савинкин
1
@IgorSavinkin и все, кто прочитает это в будущем. Если вы одновременно меняете множество элементов на один и тот же фон, вы можете использовать css для каскадного рендеринга, поместив класс для каждого элемента, который вы хотите изменить, но изменив класс общего элемента-предка. Например, css будет иметь вид #ancestor.backgroundA .Change{background-image:...}и #ancestor.backgroundB .Change{background-image...}, где #ancestorидентификатор общего предка, а .Changeкласс, применяемый ко всем элементам, к которым применяется один из фонов.
Патанджали
Забавно видеть, как все голосуют за этот ответ как за лучший, прежде чем даже подумать, будет ли хорошей практикой создать CSS с миллионом классов ... или даже лучше: CSS, содержащий миллион изображений в кодировке base64 (совет: просто подумайте о папка с миллионом, может быть, HD изображений в ней). Но да, это работает для некоторых изображений.
Габриэль Гарсия 06
Кроме того, как бы вы решили проблему добавления новых изображений к имеющимся в вашей системе изображениям? можно ли масштабировать этот подход?
Габриэль Гарсия
35

Была такая же проблема с base64. Для тех, кто в будущем столкнется с такой же проблемой:

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

Это будет работать с консоли, но не из сценария:

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

Но немного поиграв с этим, я пришел к следующему:

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

Не знаю, почему это работает с прокси-изображением, но это так. Протестировано на Firefox Dev 37 и Chrome 40.

Надеюсь, это кому-то поможет.

РЕДАКТИРОВАТЬ

Разведал немного дальше. Похоже, что иногда кодировка base64 (по крайней мере, в моем случае) нарушается с помощью CSS из-за разрывов строк, присутствующих в закодированном значении (в моем случае значение было динамически сгенерировано ActionScript).

Просто используя, например:

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

тоже работает, и даже кажется на несколько мс быстрее, чем при использовании прокси-образа.

Lutogniew
источник
2
Удаление разрывов строк исправило это для меня.
Эван
Хорошее расследование.
Sølve Tornøe
31

Попробуй, я получил успешный ответ .. он работает

$("#divId").css("background-image", "url('data:image/png;base64," + base64String + "')");
Gihansalith
источник
Кажется, если data:image/png;base64длинно, а строка определяется как переменная jquery, то не работает. Но работает, если строка определена как переменная php, например, в примере PHClaus .... Просто информация о том, что я тестировал
Андрис
13

Добавление этого трюка к следующему решению Габриэля Гарсиа -

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

Однако в моем случае это не сработало. Перемещение URL-адреса в переменную img помогло. Итак, окончательный код выглядел так

var img = "url('data:image/png;base64, "+base64Data + "')";
document.body.style.backgroundImage = img; 
Амит Кумар Рай
источник
1
@ Амит Кумар Рай, ты прав. Мне не хватало одинарных кавычек в моем коде, который вы на самом деле написали, чтобы ваш код работал.
Габриэль Гарсия 05
8

Я пробовал это (и работал у меня):

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

Синтаксис ES6:

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

Чуть лучше:

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

let node = nodeIGotFromDOM, img = imageBase64EncodedFromMyGF;
setBackground.call(node, img);
Габриэль Гарсия
источник
1
Забавно, потому что это именно тот код, о котором говорят, что он не работает.
Pimp Trizkit
У меня это тоже работает. Протестировано также на Microsoft Edge и IE 11
Ryan.C
2

Что я обычно делаю, так это сначала сохраняю полную строку в переменной, например:

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

Затем, где я хочу, чтобы JS что-то сделал с этой переменной:

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

Вы можете напрямую ссылаться на ту же переменную через PHP, используя что-то вроде:

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

Работает на меня ;)


источник
2

Это правильный способ сделать чистый звонок. Нет CSS.

<div style='background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAFCAYAAABW1IzHAAAAHklEQVQokWNgGPaAkZHxPyMj439sYrSQo51PBgsAALa0ECF30JSdAAAAAElFTkSuQmCC)repeat-x center;'></div>
user5641497
источник
<DIV стиль = 'фон: URL (данные: изображения / PNG; base64, iVBORw0KGgoAAAANSUhEUgAAABwAAAAFCAYAAABW1IzHAAAAHklEQVQokWNgGPaAkZHxPyMj439sYrSQo51PBgsAALa0ECF30JSdAAAAAElFTkSuQmCC) повтор х центр;'> </ DIV>
user5641497
Чтобы разместить код, сделайте отступ в четыре пробела или выделите его и нажмите Ctrl-K.
2

Я думаю, это поможет, Base64 обрабатывается CSS по-другому, вы должны установить тип данных изображения на base64, это поможет CSS изменить base64 на изображение и отобразить его пользователю. и вы можете использовать это из javascript, назначив фоновое изображение с помощью скрипта jquery, он автоматически изменит base64 на mage и отобразит его

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

Рами Мохаммед
источник
Ответы только на код не приветствуются. Нажмите " Изменить" и добавьте несколько слов, описывающих, как ваш код решает вопрос, или, возможно, объясните, чем ваш ответ отличается от предыдущего ответа / ответов. Я не вижу реальной разницы между этим и одним из ранее опубликованных ответов.
Ник
0

В моем случае это было просто потому, что я не установил heightи width.

Но есть еще одна проблема.

Фоновое изображение можно удалить с помощью

element.style.backgroundImage=""

но не может быть установлен с помощью

element.style.backgroundImage="some base64 data"

Jquery отлично работает.

стлебакс
источник