0

i'm trying to use localStorage to save an image, or multiple images for retrieval at a later date to upload to a server.

The current camera code is as follows:

function capturePhoto() {
    navigator.camera.getPicture(onCameraSuccess, onCameraFail, {quality: 70, destinationType : Camera.DestinationType.DATA_URL});
}

function onCameraSuccess(imageData) {
    //In our success call we want to first process the image to save in our image box on the screen.

    var image = document.getElementById('image');
    image.src = "data:image/jpeg;base64," + imageData;

    //Create a new canvas for our image holder

    var imgCanvas = document.createElement("canvas"),
    imgContext = imgCanvas.getContext("2d");

    // Make sure canvas is as big as the picture
    imgCanvas.width = image.width;
    imgCanvas.height = image.height;

    // Draw image into canvas element
    imgContext.drawImage(image, 0, 0, image.width, image.height);

    // Get canvas contents as a data URL
    var imgAsDataURL = imgCanvas.toDataURL("image/png");

    // Save image into localStorage
    try {
    // localStorage.setItem(“savedImage”, imgAsDataURL);
    localStorage.setItem("savedImage", imageData);
    alert('Image Saved');
    }
    catch (e) {
    alert("Storage failed: " + e);
    }

    var imageStorage = localStorage.getItem("savedImage");
    // myCardHolder= document.getElementById(“m1-cardStorage-image1″);
    // Reuse existing Data URL from localStorage
    var imageInfo = document.getElementById('image');
    imageInfo.src = "data:image/jpeg;base64," + imageStorage;
}

This triggers the camera, and the image captured is displayed into

<img id="image" src=""></img>

It also draws a canvas to output the image into. What i'm really trying to achieve is to capture the images base64 data to be able to store it into an array so that it may be uploaded/downloaded from a server.

Ideally i'd like to completely avoid having to display the image to the user, and simply store the images data

I may have misunderstood the localStorage/camera api a little, so any pointers would be great.

Does the image HAVE to be output into an element before the data can be stored? If i could just output it into the canvas that may never have to be shown, and extract the data from the canvas element?

Matt Meadows
  • 147
  • 2
  • 6
  • 16

2 Answers2

1

Does the image HAVE to be output into an element before the data can be stored?

Not at all, in this case anyways. You are already receiving the image as base64 data so just store that directly.

Problems:

  1. datauris can be chopped by the browser if too long
  2. if not chopped by browser on string level, the data can be chopped by localstorage itself which has a size limit (i think it's currently around 5 mb for most browsers but there is no standard here)
  3. a string uses two bytes per char so the storage is in effect the half

A better local storage is to use indexedDB.

When you read the base64 data, then you have to use an Image to show the data. Just prefix as you do with data:... etc. and remember to use correct file type.

torox
  • 460
  • 1
  • 3
  • 11
  • As the whole localstorage wouldn't contain just images, arrays of geolocation coordinates for example, would indexedDB be a more suitable option? As long as i can use indexedDB offline, and request to upload the data i'd be happy to try it out – Matt Meadows Apr 07 '15 at 13:21
  • @MattMeadows in my opinion it will. You can request larger storage space with it than 5 mb and store almost any kind of data including blobs. – torox Apr 08 '15 at 00:40
0

Last year I was trying to solve the same problem, I don't have the code right now but I followed kind of the approach taken on this answer:

How to convert image into base64 string using javascript

Remember that localStorage has a limit of 5 MB, so if you save a lot of images in b64 you can reach that limit easily. (which was my case), so I had to move my storage to somewhere else, like a sqlite or something like that.

Community
  • 1
  • 1
jfplataroti
  • 661
  • 4
  • 12