wylie
wylie

Reputation: 35

PHP Image Upload Not Resizing When Sent Via JS

I am running into issues when uploading an image sent to PHP via JS. I can upload the image fine, but I would to resize the image before moving it to it's new destination. I can also rename the image without any issues. It's really just the resizing that is the issue here.

After a lot of searching I have seen a lot of questions regarding this on SO, which is how I got to where I am now, but not one that answers this 100%. If you know of a question/answer already on SO please link me to the correct article.

Any help is much appreciated, thanks.

Here is the JS

        var test = document.querySelector('#afile');
        test.addEventListener('change', function() {
            var file = this.files[0];

            var fd = new FormData();
            fd.append('afile', file);
            // These extra params aren't necessary but show that you can include other data.
            fd.append('id', burgerId);

            var xhr = new XMLHttpRequest();
            // why wont this work in the actions directory?
            xhr.open('POST', 'actions/upload.php', true);

            xhr.upload.onprogress = function(e) {
                if (e.lengthComputable) {
                    var percentComplete = (e.loaded / e.total) * 100;
                    var uploadProcess = document.getElementById('uploadProcess');
                    uploadProcess.setAttribute('style', 'width: ' + percentComplete + '%;');
                    // uploadProcess.innerHTML = parseInt(percentComplete) + '% uploaded';
                }
            };

            xhr.onload = function() {
                if (this.status == 200) {
                    var resp = JSON.parse(this.response);

                    image = 'img/' + resp.newFileName;
                    sessionStorage.setItem('burgerLoc', image);

                    var image = document.createElement('img');
                    image.src = resp.dataUrl;
                    document.body.appendChild(image);
                };
            };

            xhr.send(fd);
            // upImage(id)
        }, false);

Here is the markup

<input type="file" name="afile" id="afile" accept="image/*"/>

Here is the PHP

$image = $_FILES['afile']['name'];
$image_tmp = $_FILES['afile']['tmp_name'];
$image_type = $_FILES['afile']['type'];

function getName($str) {
    $parts = explode('.',$str);
    $imgName = str_replace(' ', '_',$parts[0]);
    return $imgName;
}
function getExtension($str) {
    $parts = explode('.',$str);
    $ext = $parts[1];
    return $ext;
}

$image_name = stripslashes($image);
$name = getName($image_name);
$image_ext = getExtension($image_name);
$ext = strtolower($image_ext);

if($ext == 'jpg' || $ext == 'jpeg' ) {
    $ext = 'jpg';
    $src = imagecreatefromjpeg($image_tmp);
} else if($ext == 'png') {
    $src = imagecreatefrompng($image_tmp);
} else {
    $src = imagecreatefromgif($image_tmp);
}

$file_content = file_get_contents($image_tmp);
$data_url = 'data:' . $image_type . ';base64,' . base64_encode($file_content);

list($width,$height) = getimagesize($image_tmp);

// width of the main image
$new_width = 748;
$new_height = ($height / $width) * $new_width;
$img_dest = imagecreatetruecolor($new_width,$new_height);

imagecopyresampled($img_dest,$src,0,0,0,0,$new_width,$new_height,$width,$height);

// rename the file
$new_file_name = strtolower($_REQUEST['id'] . '.' . $ext);
$new_file_location = '../img/' . $new_file_name;

imagejpeg($img_dest,$new_file_name,100);

move_uploaded_file($image_tmp, $new_file_location);

imagedestroy($src);
imagedestroy($img_dest);

$json = json_encode(array(
    'dataUrl' => $data_url,
    'extension' => $ext,
    'id' => $_REQUEST['id'],
    'name' => $image,
    'newFileName' => $new_file_name,
    'type' => $image_type
));

echo $json;

Upvotes: 2

Views: 74

Answers (1)

michalh
michalh

Reputation: 2997

I would maybe try installing ImageMagick in your linux distribution and try to use this function to resize the image

http://php.net/manual/en/imagick.resizeimage.php

I have reproduced your script on my webserver... I have made modifications and came up with this.

The most significant modification is that I am using exact paths in the file locations, and that I am moving the tmp file to a real file, load that real file, resize that real file instead of trying it to do with the tmp uploaded file.

PHP:

    <?php
    $image = $_FILES['afile']['name'];
    $image_tmp = $_FILES['afile']['tmp_name'];
    $image_type = $_FILES['afile']['type'];

    function getName($str) {
        $parts = explode('.',$str);
        $imgName = str_replace(' ', '_',$parts[0]);
        return $imgName;
    }
    function getExtension($str) {
        $parts = explode('.',$str);
        $ext = $parts[1];
        return $ext;
    }

    $image_name = stripslashes($image);
    $name = getName($image_name);
    $image_ext = getExtension($image_name);
    $ext = strtolower($image_ext);
    $outputfolder = "/var/www/html/wp-content/";
    $new_file_name = strtolower($_REQUEST['id'] . '.' . $ext);
    $new_file_location = $outputfolder.$new_file_name;
    move_uploaded_file($image_tmp, $new_file_location);

    if($ext == 'jpg' || $ext == 'jpeg' ) {
        $ext = 'jpg';
        $src = imagecreatefromjpeg($new_file_location);
    } else if($ext == 'png') {
        $src = imagecreatefrompng($new_file_location);
    } else {
        $src = imagecreatefromgif($new_file_location);
    }

    list($width,$height) = getimagesize($new_file_location);

    // width of the main image
    $new_width = 748;
    $new_height = ($height / $width) * $new_width;
    $img_dest = imagecreatetruecolor($new_width,$new_height);

    imagecopyresampled($img_dest,$src,0,0,0,0,$new_width,$new_height,$width,$height);
    $resizedLocation = $outputfolder."resized_".$new_file_name;
    imagejpeg($img_dest,$resizedLocation,100);
    imagedestroy($src);
    imagedestroy($img_dest);


    $file_content = file_get_contents($resizedLocation);
    $data_url = 'data:image/jpeg;base64,' . base64_encode($file_content);

    $json = json_encode(array(
        'dataUrl' => $data_url,
        'extension' => $ext,
        'id' => $_REQUEST['id'],
        'name' => $image,
        'newFileName' => $new_file_name,
        'type' => $image_type
    ));

    echo $json;
    ?>

Your HTML/JS stays untouched.

Now this works for me flawlessly, the only thing you have to make sure the $outputfolder is writeable by the linux user under which the webeserver executing the php script is runnging (typically web-data...)

My web server:

  • CentOS Linux release 7.0.1406 (Core)
  • php.x86_64 5.4.16-23.el7_0.3
  • apache x86_64 2.4.6

Upvotes: 2

Related Questions