2

Right now i am uploading image into canvas and after uploaded image, canvas converted into image by toDataURl. If i am converting canvas into image by toDataURL then i am getting base code(Base Code will be big). I want some small url instead of BaseCode.

var canvas = new fabric.Canvas('canvas');
document.getElementById('file').addEventListener("change", function (e) {
  var file = e.target.files[0];
  var reader = new FileReader();
  reader.onload = function (f) {  
    var data = f.target.result;  
    var img = document.createElement('img');
                    img.src = data;
                    img.onload = function () {
                        if (img.width < 300 || img.height < 300)
                        {
                            alert("upload image should be greater");
                            canvas.getActiveObject().remove();
                        }
                    };
    
    fabric.Image.fromURL(data, function (img) {
      var oImg = img.set({left: 50, top: 100,width:100, height:100, angle: 00}).scale(0.9);
      canvas.add(oImg).renderAll();
      var a = canvas.setActiveObject(oImg);
      var dataURL = canvas.toDataURL({format: 'png', quality: 0.8});
      console.log("aaaaaaaaaaa" + dataURL);

      //                        console.log("Canvas Image " + dataURL);
      //                        document.getElementById('txt').href = dataURL;

    });
  };
  reader.readAsDataURL(file);
});
document.querySelector('#txt').onclick = function (e) {
  e.preventDefault();
  canvas.deactivateAll().renderAll();
  document.querySelector('#preview').src = canvas.toDataURL();
  var b= canvas.toDataURL();
  console.log(b);
}
canvas{
  border: 1px solid black;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file">
<canvas id="canvas" width="400" height="400"></canvas>
<a href='' id='txt' target="_blank">Click Me!!</a>
<br />
<img id="preview" />

JSFiddle: https://jsfiddle.net/varunPes/8gt6d7op/23/

Varun Sharma
  • 4,632
  • 13
  • 49
  • 103
  • `some small url` ... do you have anything in mind? – Jaromanda X Feb 26 '16 at 09:30
  • @JaromandaX. I have no idea. – Varun Sharma Feb 26 '16 at 09:36
  • Just for curiosity, why does it matter to have long urls? – Kaiido Feb 26 '16 at 11:53
  • @JaromandaX. When i am sending url to server then some time it will breaks(If image is larg). – Varun Sharma Feb 26 '16 at 12:02
  • your @user was wrong, but got it. Your bug seems strange, but the only front-end solution with what we get would be the first part of Jaromanda's answer : convert the dataURL to blob but don't use the URLObject, this only does work on the user side, and just for a session. Also, the blob conversion will only save 30% of the data transferred and I think that if you lose packets during the transfer, you'll have the same "bugs". You would be better to describe these bugs and the server-side instead. – Kaiido Feb 26 '16 at 13:07
  • 1
    `When i am sending url to server` - a detail that would've been useful to know in the original question – Jaromanda X Feb 26 '16 at 13:22
  • if you want a small data to send server, export to json and recreate the scene on the server. an image has a long data url because has a lot of data. you cannot do too much about that. – AndreaBogazzi Feb 27 '16 at 13:35
  • @AndreaBogazzi. I am sending data to server by ajax. It is fine or not? $.ajax({ url: url, type: 'POST', data: { frontimage: frntImg, }, – Varun Sharma Feb 27 '16 at 13:39
  • Can i convert this base code to small form? – Varun Sharma Feb 27 '16 at 13:44
  • Can i share my code with u? – Varun Sharma Feb 27 '16 at 13:45
  • 1
    There is no small form for a binary o base64 encoded png image, an image bigger than 500x500 will be several kilobytes. and you cannot do anything about it. – AndreaBogazzi Feb 27 '16 at 23:21

2 Answers2

0

The devil is in the details - nowhere in the question do you even suggest you want to send the image somewhere - the code below is limited to the client - you can only use the short form url on the client, and as mentioned in a comment, only for a session (restart browser, url is useless), or until revokeObjectURL is called

You can - if the browser supports it, use a Blob, it's URL is short

// converts a dataURI to a Blob
function dataUriToBlob(dataURI) {
    var byteString = atob(dataURI.split(',')[1]);
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    var arrayBuffer = new ArrayBuffer(byteString.length);
    var _ia = new Uint8Array(arrayBuffer);
    for (var i = 0; i < byteString.length; i++) {
        _ia[i] = byteString.charCodeAt(i);
    }
    var dataView = new DataView(arrayBuffer);
    var blob = new Blob([dataView], { type: mimeString });
    return blob;
}
// cross browser cruft
var get_URL = function () {
    return window.URL || window.webkitURL || window;
};
// ... your code, which eventually does this
var b = canvas.toDataURL();
// get an URL from the Blob
var blob = dataUriToBlob(b);
var url = get_URL().createObjectURL(blob);
console.log(url);
//
// ... when finished with the object URL
URL.revokeObjectURL(url);
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
0

If you want to avoid send dataURL, you can convert it into DataForm using this function:

function dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
    else
        byteString = unescape(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    return new Blob([ia], {type:mimeString});
}

Then, call it:

var dataURL = canvas.toDataURL('image/jpeg', 0.5);
var blob = dataURItoBlob(dataURL);
var fd = new FormData(document.forms[0]);
fd.append("canvasImage", blob);

Finally, send this form (regular or ajax).

Source answer

Community
  • 1
  • 1
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135