14

I have script:

<?php

include('db.php');
session_start();
$session_id = '1'; // User session id
$path = "uploads/";

$valid_formats = array("jpg", "png", "gif", "bmp", "jpeg");
if (isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST") {
    $name = $_FILES['photoimg']['name'];
    $size = $_FILES['photoimg']['size'];
    if (strlen($name)) {
        list($txt, $ext) = explode(".", $name);
        if (in_array($ext, $valid_formats)) {
            if ($size < (1024 * 1024)) { // Image size max 1 MB
                $actual_image_name = time() . $session_id . "." . $ext;
                $tmp = $_FILES['photoimg']['tmp_name'];
                if (move_uploaded_file($tmp, $path . $actual_image_name)) {
                    mysql_query("UPDATE users SET profile_image='$actual_image_name' WHERE uid='$session_id'");
                    echo "<img src='uploads/" . $actual_image_name . "' class='preview'>";
                } else {
                    echo "failed";
                }
            } else {
                echo "Image file size max 1 MB";
            }
        } else {
            echo "Invalid file format..";
        }
    } else {
        echo "Please select image..!";
    }
    exit;
}

?>

Is possible convert all images (png, gif etc) to jpg with 100% quality? If yes, how? I would like allow to upload png and gif, but this script should convert this files to jpg. Is possible this with PHP?

Diego Agulló
  • 9,298
  • 3
  • 27
  • 41
Steven Sacradoor
  • 253
  • 2
  • 3
  • 5
  • Look at this discussion, it was already answered [Use PHP to convert PNG to JPG with compression?][1] [1]: http://stackoverflow.com/questions/1201798/use-php-to-convert-png-to-jpg-with-compression – Davide Berra Jan 27 '13 at 16:33
  • 1
    its about converting png to jqg @DavideBerra – Raab Jan 27 '13 at 16:37

6 Answers6

49

Try this code: originalImage is the path of... the original image... outputImage is self explaining enough. Quality is a number from 0 to 100 setting the output jpg quality (0 - worst, 100 - best)

function convertImage($originalImage, $outputImage, $quality)
{
    // jpg, png, gif or bmp?
    $exploded = explode('.',$originalImage);
    $ext = $exploded[count($exploded) - 1]; 

    if (preg_match('/jpg|jpeg/i',$ext))
        $imageTmp=imagecreatefromjpeg($originalImage);
    else if (preg_match('/png/i',$ext))
        $imageTmp=imagecreatefrompng($originalImage);
    else if (preg_match('/gif/i',$ext))
        $imageTmp=imagecreatefromgif($originalImage);
    else if (preg_match('/bmp/i',$ext))
        $imageTmp=imagecreatefrombmp($originalImage);
    else
        return 0;

    // quality is a value from 0 (worst) to 100 (best)
    imagejpeg($imageTmp, $outputImage, $quality);
    imagedestroy($imageTmp);

    return 1;
}
Davide Berra
  • 6,387
  • 2
  • 29
  • 50
  • call this function instead of move_uploaded_file – Davide Berra Jan 28 '13 at 08:03
  • 2
    Use $ext == 'png' and like instead of preg_match - it works too and is slightly faster. Also, I use strtolower on $ext before the check, to handle extensions like .JPG correctly. Otherwise, excelent function, helped me a lot. +1 – Pavel V. Jan 29 '15 at 10:36
  • the /i in preg_match makes the check case insensitive – Davide Berra Jan 29 '15 at 10:38
  • 3
    One may assume that passing $_FILES['photoimg']['tmp_name'] as the $originalImage would work, but it happens to save the file as XXXXX.tmp, so the extension didn't worked. Passing $_FILES['photoimg']['name'] instead will give the correct extension, but fail to create the image (it's getting a string instead of an object. So to solve that, you may pass both info, $originalImage and $originalName and edit the function accordingly, other than that, thanks a lot Davide for a great function i've been using for years now – LordNeo Jun 08 '16 at 20:31
  • i would add $ sign at the end of every reg. pattern. Why? what about uploaded file named: **iAmjpegWithGifAndPngTypedInName.bmp** . Dollar sign will ensure that there is nothing after the extension matched in pattern – Jimmmy Mar 29 '17 at 09:14
  • what about convert to HEIC? – Mohammad Aghayari Sep 13 '22 at 20:12
11

Try using Imagick setImageFormat, for me it provides the best image quality
http://php.net/manual/en/imagick.setimageformat.php

$im = new imagick($image);

// convert to png
$im->setImageFormat('png');

//write image on server
$im->writeImage($image .".png");
$im->clear();
$im->destroy(); 
Raab
  • 34,778
  • 4
  • 50
  • 65
chill0r
  • 1,127
  • 2
  • 10
  • 26
8

Davide Berra's answer is great, so I improved the file type detection a little, using exif_imagetype() instead of relying on the file extension:

/**
*   Auxiliar function to convert images to JPG
*/
function convertImage($originalImage, $outputImage, $quality) {

    switch (exif_imagetype($originalImage)) {
        case IMAGETYPE_PNG:
            $imageTmp=imagecreatefrompng($originalImage);
            break;
        case IMAGETYPE_JPEG:
            $imageTmp=imagecreatefromjpeg($originalImage);
            break;
        case IMAGETYPE_GIF:
            $imageTmp=imagecreatefromgif($originalImage);
            break;
        case IMAGETYPE_BMP:
            $imageTmp=imagecreatefrombmp($originalImage);
            break;
        // Defaults to JPG
        default:
            $imageTmp=imagecreatefromjpeg($originalImage);
            break;
    }

    // quality is a value from 0 (worst) to 100 (best)
    imagejpeg($imageTmp, $outputImage, $quality);
    imagedestroy($imageTmp);

    return 1;
}

You must have php_exif extension enabled to use this.

Lucas Bustamante
  • 15,821
  • 7
  • 92
  • 86
  • With exit_imagetype you can also convert broken images or images that have been converted. Works much better than the answer from Davide. Strage that that got the tick, and not this. – Lukas Apr 21 '22 at 18:27
3

A small code to convert image.png to image.jpg at desired image quality:

<?php
$image = imagecreatefrompng('image.png');
imagejpeg($image, 'image.jpg', 70); // 0 = worst / smaller file, 100 = better / bigger file 
imagedestroy($image);
?>
Al Foиce ѫ
  • 4,195
  • 12
  • 39
  • 49
1

a small fix to davide's answer, the correct function for converting from BMP is "imagecreatefromwbmp" instead of imagecreatefrombmp (missing "w") also you should consider that png may be transparent, here is a way to fill it with white BG (jpeg can't apply alpha data).

function convertImage($originalImage, $outputImage, $quality){
// jpg, png, gif or bmp?
$exploded = explode('.',$originalImage);
$ext = $exploded[count($exploded) - 1]; 
if (preg_match('/jpg|jpeg/i',$ext)){$imageTmp=imagecreatefromjpeg($originalImage);}
else if (preg_match('/png/i',$ext)){$imageTmp=imagecreatefrompng($originalImage);}
else if (preg_match('/gif/i',$ext)){$imageTmp=imagecreatefromgif($originalImage);}
else if (preg_match('/bmp/i',$ext)){$imageTmp=imagecreatefromwbmp($originalImage);}
else    {    return false;}
// quality is a value from 0 (worst) to 100 (best)
imagejpeg($imageTmp, $outputImage, $quality);
imagedestroy($imageTmp);
return true;
}
Community
  • 1
  • 1
Roy B. xSITE
  • 141
  • 1
  • 6
0

From PhpTools:

/**
 * @param string $source (accepted jpg, gif & png filenames)
 * @param string $destination
 * @param int $quality [0-100]
 * @throws \Exception
 */
public function convertToJpeg($source, $destination, $quality = 100) {

    if ($quality < 0 || $quality > 100) {
        throw new \Exception("Param 'quality' out of range.");
    }

    if (!file_exists($source)) {
        throw new \Exception("Image file not found.");
    }

    $ext = pathinfo($source, PATHINFO_EXTENSION);

    if (preg_match('/jpg|jpeg/i', $ext)) {
        $image = imagecreatefromjpeg($source);
    } else if (preg_match('/png/i', $ext)) {
        $image = imagecreatefrompng($source);
    } else if (preg_match('/gif/i', $ext)) {
        $image = imagecreatefromgif($source);
    } else {
        throw new \Exception("Image isn't recognized.");
    }

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

    if (!$result) {
        throw new \Exception("Saving to file exception.");
    }

    imagedestroy($image);
}