1

I'm working on this project and ran into some complications using AWS S3 to host images. So I pivoted and decided to store the image as a Blob and let Javascript do the work of transforming the file into and out of the Blob, so I could then use AJAX and the API to store it in our DB. While this might be less than ideal, I'm still learning Javascript and hadn't worked with blobs a lot so I figured why not, time to learn.

My issue is that when I try to use a DataURI to show the image on the page it comes out as a string and not a DataURI, and therefore loads as a broken image. I haven't worked in ajax yet because I thought it better to take the image, turn it into an ascii string, put it in a blob, then get it back out before involving the API/server. Here is my html:

{% extends 'mp_app/base.html' %}
{% load staticfiles %}
{% block content %}
<div id="page-wrapper">
    <pre id="fileDisplayArea"></pre>
     <form  id="picForm" method='post'>
       {% csrf_token %}
       <input type="file" id='imgFile' name="pic" accept="image/*">
       <input type="submit" id='submitBtn'>
      <input type="submit" id="showBtn">
    </form>
 <div id="imageDisplay"></div>
 </div>
{% endblock %}
{% block javascript %}
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script type="text/javascript" src="{% static 'js/blob.js' %}"></script>
{% endblock %}

and my Javascript

//js file to turn an image into a blob, then store the blob in our API.
// next: retrive the blob and put it on the page

function textToImg(text) {
//get ascii string into binary then into an array then into a blob.
//had some strange issues using ArrayBuffer()
var file = new 
Array(atob(document.getElementById('fileDisplayArea').innerText));
file = new Blob(file, {type:'image/*'});
let displayArea = document.getElementById('imageDisplay')

//currently doesn't seem to be loading as a DataURL. It's type is string and 
//shows up as a broken image.
var reader = new FileReader();
reader.onload = function(event) {
var content = event.target.result;
img = new Image();
img.src = content;
displayArea.append(img)
console.log(img);
}
reader.onerror = function(event) {
   console.error('error, file could not be read: ' + 
   event.target.error.code);;
}
reader.readAsDataURL(file);
// TODO get data via ajax to our DB our restful API
}

//turns an image into a blob
function imgToText() {
// get file elem and get image
let file = document.getElementById('imgFile');
let img = document.getElementById('imgFile').files[0];
let displayArea = document.getElementById('fileDisplayArea');

//open a file reader and read in file, then turn it from binary to ascii
var reader = new FileReader();

reader.onload = function(event) {
    let contents = event.target.result;

    //turn to ascii string
    let asciiContents = btoa(contents);

    //add ascii string to form
    let form = {
        'file': asciiContents,
    }
    displayArea.append(form.file);
};

reader.onerror = function(event) {
    console.error('error, file could not be read');
}

//read file as a bit string
reader.readAsBinaryString(img);

// TODO send data via ajax to our DB our restful API
};

//add click event so that image is processed upon submit
$('#submitBtn').click(function(event) {
    event.preventDefault();
    imgToText();
 });

$('#showBtn').click(function(event) {
    event.preventDefault();
    textToImg();
})

The img src reads as the blob string makes me think the something is wrong with the DataURI, perhaps it isn't getting the file in the proper format. I couldn't post a screen shot because I need a better reputation. Sorry this is so verbose but I wanted to try and make a quality post. Thank you!

1
  • TLDR; When I try to show my img blob on the page via reader.readAsDataURL, the long byte64 string is read by the src attribute, not the metadata that would show the file. Commented May 4, 2017 at 13:53

1 Answer 1

2

I solved the issue. Will post here for future learners who may need this option.

textToImg() already has the string it needs, so all you need to do is get the string, add it to the file input element, (I added it as a 'value' attr), then let image.src = 'data:image/*;base64, + value attr. And you're good to go.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.