简体   繁体   中英

Canvas to base64 does not work when drawing image from file

I am drawing image from file to a HTML5 canvas. The image draws fine on canvas. When I send this to PHP to save base64 string to server I always get empty image... Empty image is only when I draw image to canvas, if I draw something like the image will save as being drawn.

For example this will be submitted to PHP and the image will be saved to disk as drawn...

var canvas = $("canvas")[0];
var context = canvas.getContext("2d"),
context.beginPath();
context.moveTo(170, 80);
context.bezierCurveTo(130, 100, 130, 150, 230, 150);
context.bezierCurveTo(250, 180, 320, 180, 340, 150);
context.bezierCurveTo(420, 150, 420, 120, 390, 100);
context.bezierCurveTo(430, 40, 370, 30, 340, 50);
context.bezierCurveTo(320, 5, 250, 20, 250, 50);
context.bezierCurveTo(200, 5, 150, 20, 170, 80);
context.closePath();
context.lineWidth = 5;
context.fillStyle = '#8ED6FF';
context.fill();
context.strokeStyle = 'blue';
context.stroke();
var dataURL = canvas.toDataURL();
var input = $("<input>").attr("type", "hidden").attr("name", "profile_pic_data").val(dataURL);
$("form").append($(input));

This one won't. This code allows user to browse for image file and crop it. The cropped image then gets drawn to canvas, which works fine, but when I send this to PHP (same way as above) I always get blank image (base64 string is also always same whatever image I select and draw)? I tried virtually everything and I have no clues where I am doing it wrong...

function loadImageFile() {
    if (document.getElementById("uploadfile").files.length === 0) return;
    var e = document.getElementById("uploadfile").files[0];
    if (!rFilter.test(e.type)) {
        return
    }
    oFReader.readAsDataURL(e)
}
var one = new CROP;
$("body").on("click", ".newupload", function () {
    $(".uploadfile").click()
});
$("body").change(".uploadfile", function () {
    loadImageFile();
    $(".uploadfile").wrap("<form>").closest("form").get(0).reset();
    $(".uploadfile").unwrap()
});
oFReader = new FileReader, rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
oFReader.onload = function (e) {
    $(".profile-pic").html('<div class="default"><div class="cropMain"></div><div class="cropSlider"></div></div>');
    one = new CROP;
    one.init(".default");
    one.loadImg(e.target.result);
}
$('#form_profile').submit(function(e) {
    var canvas = $("canvas")[0];
    var e = canvas.getContext("2d"),
        t = new Image,
        n = coordinates(one).w,
        r = coordinates(one).h,
        i = coordinates(one).x,
        s = coordinates(one).y,
        o = 240,
        u = 240;
    t.src = coordinates(one).image;
    t.onload = function () {
        e.drawImage(t, i, s, n, r, 0, 0, o, u);
    }

    var dataURL = canvas.toDataURL();
    var input = $("<input>").attr("type", "hidden").attr("name", "profile_pic_data").val(dataURL);
    $(this).append($(input));
});

This is my PHP, which should work:

$upload_dir = DOCROOT.'assets/img/profile-pics/';
$img = $_POST['profile_pic_data'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = $upload_dir.$this->current_user->id.'.png';
$success = file_put_contents($file, $data);

Answering my own solution based on comment from @Ian. The form was submitting empty canvas, because it was submitting before then Image.onload was finished drawing on canvas.

Change was needed to submit form after Image.onload is complete. Here is the updated code:

$('#btn-profile-update').click(function(e) {
    if($('.crop-img').length)
    {
        $("canvas").remove();
        $('#form_profile').after('<canvas id="profile-pic-canvas" width="240" height="240" id="canvas"/>');
        var canvas = $("canvas")[0];
        var e = canvas.getContext("2d"),
            t = new Image,
            n = coordinates(one).w,
            r = coordinates(one).h,
            i = coordinates(one).x,
            s = coordinates(one).y,
            o = 240,
            u = 240;
        t.src = coordinates(one).image;
        t.onload = function () {
            e.drawImage(t, i, s, n, r, 0, 0, o, u);
            var dataURL = canvas.toDataURL();
            var input = $("<input>").attr("type", "hidden").attr("name", "profile_pic_data").val(dataURL);
            $('#form_profile').append($(input));
            $('#form_profile').submit();
        }
    }
    else
    {
        $('#form_profile').submit();
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM