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

1

2 Answers 2

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>

Sign up to request clarification or add additional context in comments.

Comments

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>

3 Comments

Wouldn't that make browser to download the image twice?
What I want to do here is making CSS to use the image data of img Element as a background-image
I am not sure if you are looking for something like this stackoverflow.com/questions/15734546/…, but i don't think you can do something like this with CSS, yet.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.