zettz's avatar
Level 1

Save image from canvas to directory

Hi there, I need help with how to catch and save the image from canvas (I use intervention image and camanjs).

For example: after user edit their image, and click on save button, the edited image file will be created based on edited canvas image to a specific directory.

Thank you.

0 likes
5 replies
zettz's avatar
Level 1

Hi there, sorry for late reply, @bobbybouwmann , here's what I've tried so far:

Controller:

public function setavatareffect(Request $request)
    {
        $user = User::where('username', Auth::user()->username)->firstOrFail();
        $user_avatar_path = array_filter(File::allFiles('public/storage/users/' . Auth::user()->id . '-' . Auth::user()->reg_num), function ($user_avatar_path)
            {
                return preg_match('/\b' . Auth::user()->reg_num. '(.*)/', $user_avatar_path);
            });
        $path = 'public/users/' . Auth::user()->id . '-' . Auth::user()->reg_num . '/' . 'edited_avatar';
        $save_path = 'public/storage/users/' . Auth::user()->id . '-' . Auth::user()->reg_num . '/' . 'edited_avatar';
        if ( !Storage::exists ($path) ) {
            Storage::MakeDirectory($path, 0755, true);
        }
        foreach ( $user_avatar_path as $user_path )
        {
            $image = Image::make($user_path);
            $image->save($save_path . '/e_' . Auth::user()->u_avatar);
        }
        //Alert::success('Your avatar has been set up successfully.', 'Success')->persistent("Confirm");
        return redirect()->back();
        //return redirect()->route('users.profile', Auth::user()->username);
    }

View:

{{ Form::model($user, ['method' => 'PATCH', 'route' => ['users.set_effect', Auth::user()->username ], 'id' => 'profile_avatar', 'data-toggle' => 'validator', 'role' => 'form']) }}
<center>
    <canvas id="image" style="max-width:100%; border:1px solid #000000;">
    </canvas>
</center>
<a href="#" id="resetbtn" class="btn btn-success" style="width:125px; height:100px;">
    Reset
</a>
<a href="#" id="noisebtn" class="btn btn-primary" style="width:125px; height:100px;">
    Noise
</a>
<button type="submit" class="btn btn-warning pull-right">
    <i class="fa fa-save"></i> Save Changes
</button>
{{ Form::close() }}

Script:

$(function() {
    var canvas = document.getElementById('image');
    var ctx = canvas.getContext('2d');
    var img = new Image();
    img.crossOrigin = '';
    img.src = '{{ url(dirname($user_path) . '/' . basename($user_path)) }}';
    img.onload = function() {
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img, 0, 0, img.width, img.height);
    }
    var $reset = $('#resetbtn');
    var $noise = $('#noisebtn');
    $reset.on('click', function(e) {
        e.preventDefault();
        $('input[type=range]').val(0);
        Caman('#image', img, function() {
            this.revert(false);
            this.render();
        });
    });
    $noise.on('click', function(e) {
        e.preventDefault();
        Caman('#image', img, function() {
                this.noise(10).render();
            });
    });

Route:

Route::patch('/effects', 'UserProfileController@setavatareffect')->name('users.set_effect');

Everything works fine, except I can't get the canvas image when the save button is clicked. Thank you.

bobbybouwmann's avatar
Level 88

So first of all you need to post the canvas correctly to your controller. In your case you need to do something like this

var canvas = document.getElementById('image');
var dataURL = canvas.toDataURL();

The dataUrlshould be posted to your controller. You can do that with an Ajax for example

$.ajax({
    type: "POST",
    url: "/your-url-here",
    data: { 
        imgBase64: dataURL
    }
}).done(function(o) {
    console.log('saved'); 

    // Do here whatever you want.
});

Once you have posted it you need to parse the the dataUrland convert it to an actual image.

public function saveImage(Request $request)
{
    $image = Image::make($request->get('imgBase64'));
    $image->save('public/bar.jpg');
}

Note that I'm using the intervention library here: http://image.intervention.io/api/make

zettz's avatar
Level 1

Hi there @bobbybouwmann , thx, I just tried it and modify a little according to my need and it worked nicely. Thank you for your time.

Please or to participate in this conversation.