2

Is it possible to load image data stored in img element into a css background-image property?

For example, assume that we have downloaded image data into 'img' element

var img = Image();
img.src = '/foo/bar'
img.onload = ....

Then, I'd like to load that image to the css background-image property

.something {
  background-image: img
}

Is this possible? Mixing using image Element and css background-image property so that CSS can use image data in img element as a background-image

Jaebum
  • 1,397
  • 1
  • 13
  • 33

2 Answers2

2

Edit: This first answer was only ever meant to address the original question asked around working with an image element. Scroll down for a better alternative to fetching image data.

If you are trying to safely capture the raw data to use at a later point, you can draw the image onto a canvas element in order to generate a base-64 encoded data-URL. Though this solution will be subject to same-origin restrictions.

const getImageData = imageElement => {
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    canvas.width = imageElement.width
    canvas.height = imageElement.height
    ctx.drawImage(imageElement, 0, 0)
    return canvas.toDataURL()
}

const img = new Image
img.addEventListener('load', () => 
    // assign to some CSS rule
    console.log(getImageData(img))
)
img.src = '/foo/bar'

Reading between the lines however your comment, "wouldn't that make the browser download the image twice?" sounds like a misunderstanding - browsers already cache resources and you can reuse asset URLs in any context in your page (i.e. HTML / CSS / JS) and unless explicitly circumvented, rely on them only being downloaded once.


Alternatively, it would be cleaner to load the image as a Blob.

Note: I'm using a CORS proxy here purely to facilitate a runnable example. You probably wouldn't want to pass your own assets through an arbitrary third-party in a production environment.

const getImage = async url => {
    const proxy = 'https://cors-anywhere.herokuapp.com/'
    const response = await fetch(`${proxy}${url}`)
    const blob = await response.blob()
    return URL.createObjectURL(blob)
}

const imageUrl = 
    'https://cdn.sstatic.net/Sites/stackoverflow/' +
    'company/img/logos/so/so-logo.png?v=9c558ec15d8a'
    
const example = document.querySelector('.example')

getImage(imageUrl).then(objectUrl => 
    example.style.backgroundImage = `url(${objectUrl})`
)
.example {
    min-height: 140px;
    background-size: contain;
    background-repeat: no-repeat;
}
<div class="example"></div>
Emissary
  • 9,954
  • 8
  • 54
  • 65
0

You can do this with JQuery

var img = new Image();
img.src = 'http://placehold.it/350x150';
$('div').css('background-image', 'url('+img.src+')');
div {
  height: 150px;
  width: 300px;
  background-size: cover;
  background-position: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>

Or pure Javascript

var img = new Image();
img.src = 'http://placehold.it/350x150';
document.getElementById('element').style.backgroundImage = "url("+img.src+")";
div {
  height: 150px;
  width: 300px;
  background-size: cover;
  background-position: center;
}
<div id="element"></div>
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
  • Wouldn't that make browser to download the image twice? – Jaebum Mar 20 '16 at 12:27
  • What I want to do here is making CSS to use the image data of img Element as a background-image – Jaebum Mar 20 '16 at 12:28
  • I am not sure if you are looking for something like this http://stackoverflow.com/questions/15734546/using-html-data-attribute-to-set-css-background-image-url, but i don't think you can do something like this with CSS, yet. – Nenad Vracar Mar 20 '16 at 12:34