0

I have a form with some data and 2 input for upload image, I have already read other questions on the site, but there are really many answers. I need only to reduce the size of the image before the upload to be faster for the user. what I can not understand is how to reduce the image and retrieve it from the mailer.php.

<?php

    $nome        = $_POST["nome-locale"];
    $email       = $_POST["email"];
    $telefono    = $_POST["telefono"];
    $indirizzo   = $_POST["indirizzo"];
    $civico      = $_POST["civico"];
    $citta       = $_POST["citta"];
    $provincia   = $_POST["provincia"];
    $cap         = $_POST["cap"];
    $titolare    = $_POST["titolare"];
 $cf          = $_POST["codice_fiscale"]; 
    $declaration = isset($_POST["declaration"]) ? $_POST['declaration'] : 'No';
    $newsletter  = isset($_POST["newsletter"]) ? $_POST['newsletter'] : 'No';
    $data        = date('d-m-Y'); 


    $body = "<br>nome-locale:" . $nome . "<br>Email:" . $email . "<br>TelefonoLocale:" . $telefono . "<br>Indirizzo:" . $indirizzo . "<br>Civico:" . $civico . "<br>Città:" . $citta . "<br>Provincia:" . $provincia . "<br>Cap:" . $cap . "<br>Nome titolare:" . $titolare . "<br>CF:" . $cf . "<br>Declaration:" . $declaration . "<br>newsletter:" . $newsletter;


    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\Exception;

    require 'PHPMailer/src/Exception.php';
    require 'PHPMailer/src/PHPMailer.php';
    require 'PHPMailer/src/SMTP.php';
    // Instantiation and passing `true` enables exceptions
    $mail = new PHPMailer(true);

    $mail->isSMTP(); // Send using SMTP
    $mail->Host       = x // Set the SMTP server to send through
    $mail->SMTPAuth   = true; // Enable SMTP authentication
    $mail->Username   = 'x // SMTP username
    $mail->Password   = 'x; // SMTP password
    $mail->SMTPSecure = 'ssl'; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` also accepted
    $mail->Port       = 465; // TCP port to connect to

    if (array_key_exists('menu1', $_FILES) && array_key_exists('menu2', $_FILES)) {
        try {
            //Server settings
            // First handle the upload
            // Don't trust provided filename - same goes for MIME types
            // See http://php.net/manual/en/features.file-upload.php#114004 for more thorough upload validation
            $menu1_filename = $_FILES['menu1']['name'];
            $menu2_filename = $_FILES['menu1']['name'];

            $menu1 = tempnam(sys_get_temp_dir(), hash('sha256', $menu1_filename));
            $menu2 = tempnam(sys_get_temp_dir(), hash('sha256', $menu2_filename));

            if (move_uploaded_file($_FILES['menu1']['tmp_name'], $menu1) &&
                move_uploaded_file($_FILES['menu2']['tmp_name'], $menu2)) {
                // Upload handled successfully
                // Now create a message
                //Recipients
                $mail->setFrom('feed@vaimenu.it', $data);
                $mail->addAddress('feed@vaimenu.it'); // Add a recipient
                $mail->isHTML(true); // Set email format to HTML
                $mail->Subject = ('Iscrizione: ' . $nome);
                $mail->Body = $body;
                $mail->AltBody = 'Iscrizione ricevuta da landing page';

                // Attach the uploaded file
                $mail->AddAttachment($menu1, $menu1_filename);
                $mail->AddAttachment($menu2, $menu2_filename);
                $mail->send();

                $mail->ClearAllRecipients();
                $mail->clearAddresses();
                $mail->ClearAttachments();

                $mail->isHTML(true);
                $mail->Subject = ('Benvenuto, ' . $nome);
                $mail->setFrom('feed@vaimenu.it', 'Vaimenu.it');
                $mail->addAddress($email);

                $message = file_get_contents('Benvenuto.html');
                $message = str_replace('%Nome%', $nome, $message);

                $mail->MsgHtml($message);

                if (!$mail->send()) {
                    $response['error']   = true;
                    $response['message'] = "Message could not be sent. Some thing went wrong Mailer Error: " . $mail->ErrorInfo;
                } else {
                    $response['success'] = true;
                }
            } else {
                $response['error']   = true;
                $response['message'] = 'Failed to move file to ' . $menu1;
            }

            echo json_encode($response);
        } catch (Exception $e) {
            $response['error']   = true;
            $response['message'] = "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";

            echo json_encode($response);
        }
    }
?>
<form role="form" method="post" id="myform" action="mailer.php" enctype="multipart/form-data" >
.......
.......
<div class="form-group was-validated">
        <label class="control-label">Menu1</label>
        <input type="file" name="menu1" accept=".jpg,.jpeg,.pdf,.png" required>
       </div>
       <div class="progress">
        <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
       </div>
       <br>
                          <div class="form-group was-validated ">
       <label class="control-label">Menu2</label>
        <input type="file" name="menu2"  accept=".jpg,.jpeg,.pdf,.png" required>
       </div>
       <div class="progress">
        <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
       </div>
              
              
              ....
              <button class="btn btn-success btn-lg fa-pull-right" type="submit">Finito!</button>
              </form>
Trect
  • 2,759
  • 2
  • 30
  • 35
  • 1
    *"I need only to reduce the size of the image before the upload"* ... PHP runs on the server so it can't do anything with the image **until** it's been uploaded. – CD001 Feb 24 '20 at 13:34
  • @Fabio what do you mean by 'before upload`?. Do you mean you want to shrink the image with JavaScript, before it get's uploaded to the server? Or do you mean you need the image made smaller on the server by PHP before it is sent by email? – yunzen Feb 24 '20 at 13:35
  • Possible duplicate of https://stackoverflow.com/a/24015367/476951 – yunzen Feb 24 '20 at 13:38
  • You can just resize image after upload with php –  Feb 24 '20 at 13:39
  • Yes, not resize with PHP, I mean that the image have to resize before the user press submit button, to be faster when the form is send. –  Feb 24 '20 at 13:57

2 Answers2

0

This PHP function will reduce image size after upload

<?php  
    // Compress image
    function compressImage($source, $destination, $quality) {

        $info = getimagesize($source);

        if ($info['mime'] == 'image/jpeg') {
            $image = imagecreatefromjpeg($source);
        } elseif ($info['mime'] == 'image/gif') {
            $image = imagecreatefromgif($source);
        } elseif ($info['mime'] == 'image/png') {
            $image = imagecreatefrompng($source);
        }

        imagejpeg($image, $destination, $quality);

    }
?>

Save into directory

$img_dir = "img/";
// $img = ""; your image

compressImage($_FILES["img"]["tmp_name"], $img_dir.$img, 60);

best for images below 10MB or more

  • But with this code the user have to upload the file and after is resize , it's not faster to send form –  Feb 24 '20 at 14:01
  • Validate image size first, you can set a max. size of 5mb to make compression faster. –  Feb 24 '20 at 14:04
  • Why allow users upload bigger images of MB size to mail/through mail –  Feb 24 '20 at 14:05
0

PHP runs on server and you cannot compress the image unless the image is uploaded to the server. But you can use Javascrypt to compress the Image before uploading. Depending on the framework you are using there are plenty of solutions to solve this problem. Modern website often compress the media before they are uploaded to reduce the bandwidth, the same reason you had mentioned.

If you are using React, AngularJS or VueJS you can use browser-image-compression npm package. This library has plenty of functions. You can both compress by reducing the image JPEG quality or just change the dimensions.

If all you care is just reduce the size (width and height) and nothing to do with the quality you can just use a simple Javascrypt function as shows here. I am reproducing a part of it for the sake of convenience.

// from an input element
var filesToUpload = input.files;
var file = filesToUpload[0];

var img = document.createElement("img");
var reader = new FileReader();  
reader.onload = function(e) {img.src = e.target.result}
reader.readAsDataURL(file);

var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);

var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img.width;
var height = img.height;

if (width > height) {
  if (width > MAX_WIDTH) {
    height *= MAX_WIDTH / width;
    width = MAX_WIDTH;
  }
} else {
  if (height > MAX_HEIGHT) {
    width *= MAX_HEIGHT / height;
    height = MAX_HEIGHT;
  }
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);

var dataurl = canvas.toDataURL("image/png")
Trect
  • 2,759
  • 2
  • 30
  • 35