有没有一种方法将背景图像设置为base64编码的图像?

149
我想在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...";

有没有办法做到这一点?


2
url(' should work, my problem was that the ActionScript dataURL actually had newlines, and I had to replace(/\n/g, '') - neaumusic
yourimageelement.setAttribute('style', 'background-image:url('+ yourbase64data +')'); - Hanna Rose
10个回答

161

我试图像您一样做,但是显然背景图片无法使用编码数据。作为替代方案,我建议使用CSS类和这些类之间的切换。

如果您正在“即时生成”数据,则可以动态加载CSS文件。

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;
.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=");
}
<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" />

我在这里调试了一下,点击按钮就可以切换div的背景:http://jsfiddle.net/egorbatik/fFQC6/


谢谢,但我处理大量元素,所以交换类不切实际。 - Igor Savinkin
1
@IgorSavinkin和未来的读者,如果你要同时将许多元素更改为相同的背景,则可以使用CSS级联呈现,通过在要更改的每个元素上放置一个类,但更改共同祖先元素的类。例如,CSS将是#ancestor.backgroundA .Change{background-image:...}#ancestor.backgroundB .Change{background-image...},其中#ancestor是共同祖先的ID,.Change是应用于所有要应用其中一个背景的元素的类。 - Patanjali
看到大家在考虑是否将CSS创建成拥有百万个类的样式表,或者更好的是,一个包含百万张Base64编码图像的CSS样式表之前,就把这个回答评为最佳,这实在是挺有趣的(提示:想象一下里面装着百万张高清图片的文件夹)。但是,这种方法仅适用于少量的图像。 - gabriel garcia
另外,您如何解决将新图像添加到可用图像系统的问题?这种方法是否可扩展? - gabriel garcia

49

我曾经也遇到了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上进行了测试。

希望对某些人有所帮助。

编辑

进一步调查发现,在CSS中有时会因编码值中存在换行符(在我的情况下是动态由ActionScript生成的值)而导致base64编码出现问题。

只需简单地使用例如:

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

这种方法也可行,而且似乎比使用代理图像快几毫秒。


5
去掉换行符后,问题就解决了。 - Evan
良好的调查。 - Sølve T.
这个答案可能很旧,但它仍然是一个坚实有效的答案!而且它阻止了我不停地撞墙。 - Phaelax z

36

尝试这个, 我收到了成功的响应..它正在工作

$("#divId").css("background-image", "url('data:image/png;base64," + base64String + "')");

如果data:image/png;base64太长,并将该字符串定义为jQuery变量,则无法正常工作。但是,如果将字符串定义为php变量,例如PHClaus的示例,则可以正常工作...这只是我测试过的信息。 - Andris

13

将这个技巧添加到Gabriel Garcia的以下解决方案中 -

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
@Amit Kumar Rai 你是正确的。我在我的代码中缺少了单引号,你实际上已经写了,所以你的代码可以运行。 - gabriel garcia

11

我试过这个方法(对我有效):

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

4
这是纯粹调用的正确方式。无需CSS。
<div style='background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAFCAYAAABW1IzHAAAAHklEQVQokWNgGPaAkZHxPyMj439sYrSQo51PBgsAALa0ECF30JSdAAAAAElFTkSuQmCC)repeat-x center;'></div>

<div style='background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAFCAYAAABW1IzHAAAAHklEQVQokWNgGPaAkZHxPyMj439sYrSQo51PBgsAALa0ECF30JSdAAAAAElFTkSuQmCC)repeat-x center;'></div> - user5641497
要发布代码,请将其缩进四个空格或选择它,然后按Ctrl-K。 - user3717023

3

在使用数据URI时不要在url中使用引号。

li {
  background:
    url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7)
    no-repeat
    left center;
  padding: 5px 0 5px 25px;
}

使用引号是否违反CSS /数据URI的规定?您提供的链接未涉及此问题。 - gth
显然这也应该可以工作,但由于某些原因,对我来说只有不带引号的数据URI才能正常工作。 - Wellington

3

我认为这会有所帮助,

CSS以不同的方式处理Base64,你应该将图像的数据类型设置为base64,这将帮助CSS将base64转换为图像并显示给用户。你可以使用jQuery脚本通过分配背景图片来从JavaScript中使用它,它会自动将base64更改为图像并显示出来。

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


不鼓励只提供代码的回答。请点击[编辑],并添加一些概括您的代码如何解决问题的文字,或者解释您的答案与先前答案之间的区别。我看不出这个答案与之前发布的答案有什么真正的区别。 - Nick

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; ?>">

符合我的要求;)

0
在我的情况下,这只是因为我没有设置heightwidth
但还有另一个问题。
背景图片可以使用以下方式移除:

element.style.backgroundImage=""

但是无法使用以下方式进行设置

element.style.backgroundImage="一些base64数据"

Jquery正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接