Search code examples
vue.jsflaskwebsocketbase64vuex

Vue image from base64 or ArrayBuffer


I have a flask backend, which sends an image to the vue frontend as described here:

with open('my_image_file.jpg', 'rb') as f:
    image_data = f.read()
emit('IMAGE', {'image_data': image_data})

On the vue frontend, the image should ultimately be shown on the webpage. I guess the easiest way would be to somehow save the image in the static Folder. I would have an action like this in my store:

const actions = {
  SOCKET_IMAGE (commit, image) {
    console.log("image received")

    /* What needs to be done to save image in 'static/' ?*/

    commit.commit('image_saved')
  }
}

I am also open for alternative ways to save the image and render it on the webpage. Can I save the image directly in the vuex store?


Solution

  • You can store the image data in Vuex

    Store:

    const state = {
      imgData: null
    }
    

    Assuming you're getting base64 from the API, commit the raw data:

    commit('SET_IMAGE_DATA', image);
    

    Or, if you're getting an ArrayBuffer, convert it first:

    function _arrayBufferToBase64( buffer ) {
        var binary = '';
        var bytes = new Uint8Array( buffer );
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode( bytes[ i ] );
        }
        return window.btoa( binary );
    }
    
    const imgData = _arrayBufferToBase64(image)
    commit('SET_IMAGE_DATA', imgData);
    

    ArrayBuffer to base64 method found here

    And use it in your template :

    <template>
      <div>
        <img :src="'data:image/png;base64,' + $store.state.imgData" />
      </div>
    </template>