Search code examples
javascriptimageimage-compression

Compressor.js - Upload image via normal form submission (no Ajax)


I'm using the following script to compress images on the client side before uploading:

https://github.com/fengyuanchen/compressorjs

I can upload the images fine via Ajax using the following code:

// Following is a form with #name and #image input fields and #submit button:

var formData = new FormData();

$('#image').change(function(e) {
    var img = e.target.files[0];
    new Compressor(img, {
        quality: 0.8,
        maxWidth: 1600,
        maxHeight: 1600,
        success(result) {
            formData.append('image', result, result.name);
        },
    });
});

$('#submit').click(function() {
    formData.append('name', $('#name').val());

    $.ajax({
        type: 'POST',
        url: 'form-script.php',
        data: formData,
        contentType: false,
        processData: false
    }).done(function() {

    }); 
});

I need to upload the image via normal form submission -no Ajax-, but I couldn't manage to do it. I am asking how to use result in the following code, so that the compressed image will be submitted when the form is submitted. As a side note, I use PHP server side.

$('#image').change(function(e) {
    var img = e.target.files[0];
    new Compressor(img, {
        quality: 0.7,
        maxWidth: 1200,
        maxHeight: 1200,
        success(result) {
            // ??
        },
    });
});

Thank you.


Solution

  • After further research and trial, I was able to find how to post the compressed image without Ajax, using the following:

    Form:

    <form id="form" action="" method="post" enctype="multipart/form-data">
        <input type="text" id="name" name="name">
        <input type="file" id="image">
        <!-- A hidden input is needed to put the image data after compression. -->
        <input type="hidden" id="image-temp" name="image">
        <input type="submit" name="submit" value="Submit">
    </form>
    

    Image compression:

    $('#image').change(function(e) {
        var img = e.target.files[0];
        new Compressor(img, {
            quality: 0.8,
            maxWidth: 1600,
            maxHeight: 1600,
            success(result) {
                var reader = new FileReader();
                reader.readAsDataURL(result);
                reader.onloadend = function() {
                    var base64data = reader.result;
                    $('#image-temp').val(base64data);
                }
            },
        });
    });
    

    Server side (PHP):

    if (isset($_POST['submit'])) {
        /* Get other form data as usual. */
        $name = $_POST['name'];
        
        if (!empty($_POST['image'])) {
            file_put_contents('images/image.jpg', file_get_contents($_POST['image']));
        }
    }
    

    Use what you want for directory (images/) and file name (image.jpg) as you wish.

    For multiple images, use HTML/CSS classes for JS part, and a loop for PHP part.