I'm trying to compress and upload an image to the server with PHP. The upload are working correctly (without any errors), however the image size remains the same after the upload has completed. Could someone please advise what I could possibly be doing wrong?
Please find the code below:
public function addcoverimageAction()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Sanitize POST array
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
$userid = $this->route_params['userid'];
$thisuser = $userid;
$postid = $this->route_params['postid'];
$path_parts = pathinfo($_FILES['file']['name']);
$filename = $path_parts['filename'] . '_' . microtime(true) . '.' . $path_parts['extension'];
$directoryName = dirname(__DIR__) . "/images/$thisuser/listings/$postid/coverimage/";
// Check if directory exist
if (!is_dir($directoryName)) {
//If directory does net exist - create directory
mkdir($directoryName, 0777, true);
}
// Compress image
function compressImage($source, $destination, $quality)
{
$info = getimagesize($source);
if ($info['mime'] == 'image/jpeg') $image = imagecreatefromjpeg($source);
elseif ($info['mime'] == 'image/png') $image = imagecreatefrompng($source);
imagejpeg($image, $destination, $quality);
}
compressImage($_FILES['file']['tmp_name'], $directoryName . $filename, 60);
// Upload image
move_uploaded_file($_FILES['file']['tmp_name'], $directoryName . $filename);
}
$this->post = Post::findByID($postid);
Post::updateCoverimage($filename, $postid);
}
If it is working, then you're immediately overwriting the compressed file with the original, via the move_uploaded_file command, because you're sending it to the same destination as the compressed file, which was an earlier step.
The move_uploaded_file command is unnecessary in this case - you can remove it
Related
I have a script that sends an image it is saved as a .gif as declared in the movie.php file that will be listed below.
However, as I understand it, it creates an image from the gif making it useless for display because it simply becomes a static image .gif.
Anyway
I wanted to know how I can upload this file and ignore this function (imagecreatefromgif) I tried to change it in several ways and when I remove it I get an error, someone could help me work around this so that the gif will be sent and not be converted to a gif file static. basically I wanted that the way I sent the gif it would only be renamed with function imageGenerateName () but that it would keep all its size and property.
Every help is welcome.
Thanks in advance
.
Movie.php code:
<?php
class Movie {
public function imageGenerateName() {
return bin2hex(random_bytes(60)) . ".gif";
}
}
movie-process.php code
<?php
// Upload img
if(isset($_FILES["image"]) && !empty($_FILES["image"]["tmp_name"])) {
$image = $_FILES["image"];
$imageTypes = ["image/gif"];
$jpgArray = ["image/gif"];
// Check img type
if(in_array($image["type"], $imageTypes)) {
// Check img type
if(in_array($image["type"], $jpgArray)) {
$imageFile = imagecreatefromgif($image["tmp_name"]);
} else {
$imageFile = imagecreatefromgif($image["tmp_name"]);
}
// image name
$imageName = $movie->imageGenerateName();
imagegif($imageFile, "./img/movies/" . $imageName, 100);
$movie->image = $imageName;
}
}
// Upload img
if(isset($_FILES["image"]) && !empty($_FILES["image"]["tmp_name"])) {
$image = $_FILES["image"];
$imageTypes = ["image/gif"];
$jpgArray = ["image/gif"];
// Check img type
if(in_array($image["type"], $imageTypes)) {
// check type is gif
if(in_array($image["type"], $jpgArray)) {
$imageFile = imagecreatefromgif($image["tmp_name"]);
}
// generete img name
$movie = new Movie();
$imageName = $movie->imageGenerateName();
imagegif($imageFile, "./img/movies/" . $imageName, 100);
$movieData->image = $imageName;
}
}
Unfortunately, the imagecreatefromgif function will only read the first image of the gif as the PHP manual says.
I tried before to solve this, but there is no turnaround other than uploading the image without touching it. PHP uses the GD library and this library doesn't have the proper functionality to deal with gif images other than just saving the image with the *.gif extension.
So, this is my suggested solution:
// generete img name
$movie = new Movie();
$imageName = $movie->imageGenerateName();
move_uploaded_file($_FILES["image"]["tmp_name"],"./img/movies/" . $imageName);
$movieData->image = $imageName;
I think since you say you just want to save it as it is, with the same size and its all properties, you can use below code
<?php
$allowed = array('gif');
$filename = $_FILES["image"]['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if (in_array($ext, $allowed)) {
// generete img name
$movie = new Movie();
$imageName = $movie->imageGenerateName();
$uploadResult = move_uploaded_file($_FILES['image']['tmp_name'], dirname( dirname( __FILE__ ) ).'/img/movies/'. $imageName );
if($uploadResult === true ){
$movie->image = $imageName;
}else{
throw new \Exception('Unable to copy file to the given path');
}
}
Or if you have access to the Imagick lib php extension refer to below link on how to install this php-extension
https://www.php.net/manual/en/imagick.setup.php
then using the functions in that library you can do
<?php
$allowed = array('gif');
$filename = $_FILES["image"]['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if (in_array($ext, $allowed)) {
$image = new Imagick();
$image->readImage($_FILES["image"]["tmp_name"]);
$image = $image->coalesceImages();
foreach ($image as $frame) {
$frame->cropImage($crop_w, $crop_h, $crop_x, $crop_y);
$frame->thumbnailImage($size_w, $size_h);
$frame->setImagePage($size_w, $size_h, 0, 0);
}
$image = $image->deconstructImages();
$image->writeImages(dirname( dirname( __FILE__ ) ).'/img/movies/'. $imageName, true);
}
?>
I've spend all day figuring out how to store an image in tmp, change its size and then upload it to my S3 bucket. The S3 bucket works fine and i am able to upload images when i don't resize. The resize function is the createThumbnail function and works fine when not combined with S3 probably because it's a wrong format or something. The second file "init.php" contains all the functions. The images are uploaded to the temp folder but when i run the script it doesn't get uploaded after it's resized. I don't get any error logs on localhost and when i upload the code to my AWS instance it just returns a internal server error but the error log in my instance is oddly empty... I need some fresh eyes on this issue.
banner_image.php
<?php
include "init.php";
if (#session($_SESSION["buddy"])){
$valid_file_formats = array("jpg","png","jpeg");
if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST" && !empty($_FILES['banner_image']['tmp_name']) && !empty($_FILES['banner_image']['name'])){
$folder = usernameFromEmail($_SESSION["user"]); // session based on users email
$buddy = $_SESSION["user"];
$name = $_FILES['banner_image']['name'];
$size = $_FILES['banner_image']['size'];
$path = $folder."/cover/"; // path to image folder
$temp = explode(".", $name);
$newfilenameKey = round(microtime(true)); // generating random file name
$newfilename = $newfilenameKey . "." . "png"; // always using png
if(strlen($newfilename) && strlen($name)) {
$ext = explode(".", $name);
$ext = end($ext);
if(in_array($ext,$valid_file_formats)) { // valid file format array check
if($size<=(10485760)) { // size check in bits
$tmp = $_FILES['banner_image']['tmp_name'];
$file_name = $path.$newfilename; // full path including file name
if(putS3IMG($bucket, $file_name, $tmp)){ // upload untouched image to S3 bucket
list($width, $height) = getimagesize($tmp);
$type = 2;
$w = 300;
$h = 300 * ($height / $width);
// getting new dimensions for the new image
if(createThumbnail(1,$tmp,$w,$h,$path,$file_name) == 1){ // function for smaller image
return json_encode(array("succ" => 1));
}
}
}
}
}
}
}
?>
here is my init.php file included in the banner_image.php file which contains my functions.
<?php
// connection to S3Client .... $client
function createThumbnail($type,$image_name,$new_width,$new_height,$uploadDir,$moveToDir){
global $bucket;
//$type: defines the name of the new file
//image_name: tmp name
//uploadDir: path
//moveToDir: files new path incl. file name
$mime = getimagesize($image_name);
if($mime['mime']=='image/png') {
$src_img = imagecreatefrompng($image_name);
} else if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
$src_img = imagecreatefromjpeg($image_name);
}
$old_x = imageSX($src_img);
$old_y = imageSY($src_img);
$thumb_w = $new_width;
$thumb_h = $new_height;
$dst_img = ImageCreateTrueColor($thumb_w,$thumb_h);
$background = imagecolorallocate($dst_img, 0, 0, 0);
imagecolortransparent($dst_img, $background);
imagealphablending($dst_img, false);
imagesavealpha($dst_img, true);
imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);
$image_name_new = explode(".", $moveToDir);
if ($type == 1){
$new_image_name = $image_name_new[0] . "_thumb." . $image_name_new[1];
} else if ($type == 2){
$new_image_name = $image_name_new[0] . "_image." . $image_name_new[1];
}
$tmpPath = tempnam(sys_get_temp_dir(), $new_image_name); // getting temporary directory
if($mime['mime']=='image/png') {
imagepng($dst_img,$tmpPath,8);
} else if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
imagejpeg($dst_img,$tmpPath,80);
}
imagedestroy($dst_img);
imagedestroy($src_img);
if(putS3IMG($bucket, $image_name, $tmpPath)){ // this part does not work
return 1;
} else {
return 2;
}
}
function putS3IMG($bucket, $file_name, $tmp){ // function uploading to my bucket
//file_name is with directories
//tmp is $_FILES tmp_name
global $client;
$result = $client->putObject([
'Bucket' => $bucket,
'Key' => $file_name,
'SourceFile' => $tmp
]);
if ($result){
return true;
}
return false;
}
SOLUTION:okay, so eventually i ended up using AWS lambda which solved the issue but it isn't a free solution. So, if any of you come up with a solution that allow you to resize without using third party tools feel free to comment it in order to make life easier for the next programmers viewing this question.
I am trying to get filesize of images from a specific folder AFTER and BEFORE they are optimized.
I get same size for $imgsize as well as $newsize even though the latter appears AFTER they images are optimized. What i actually want is that it gets me the NEW size, not the old!
$array has the list of URLs for images (absolute URLs, belongs to another server)
(also let me know, is this fine that i'm replacing the same image after optimizing size in this part $optimized_image= compress_image($path, $path, 50); ) ?
Here is my code:
$f_path='newfolder';
foreach ($array as $imglink)
{
$image = file_get_contents($imglink);
$path= $f_path . "/" . basename($imglink);
$new_image=file_put_contents($path , $image);
$imgsize = filesize($path);
$optimized_image= compress_image($path, $path, 50);
$newsize = filesize($path);
$percentage = ($imgsize / $newsize)*100;
echo $imgsize . "<br/>"; //this size appears fine
echo $newsize; //gives same size as above, no change!
}
And here is the function i'm using for compressing image (which seem to work perfectly fine to me)
function compress_image($src, $dest , $quality)
{
$info = getimagesize($src);
if ($info['mime'] == 'image/jpeg')
{
$image = imagecreatefromjpeg($src);
}
elseif ($info['mime'] == 'image/gif')
{
$image = imagecreatefromgif($src);
}
elseif ($info['mime'] == 'image/png')
{
$image = imagecreatefrompng($src);
}
else
{
die('uknown format');
}
imagejpeg($image, $dest, $quality);
}
Thanks to #u_mulder for the answer. The clearstatcache worked perfectly and solved the problem! :) This is because it deletes the old variable data.
Here is the function that compress image file.
function compress_image($source_url, $destination_url, $quality) {
$info = getimagesize($source_url);
if ($info['mime'] == 'image/jpeg'){
$image = imagecreatefromjpeg($source_url);
}elseif ($info['mime'] == 'image/gif') {
$image = imagecreatefromgif($source_url);
}elseif ($info['mime'] == 'image/png') {
$image = imagecreatefrompng($source_url);
}imagejpeg($image, $destination_url, $quality);
return $destination_url;
}
$filename = compress_image($_FILES["home_image"]["tmp_name"], $_FILES["home_image"]["name"], 80);
$buffer = file_get_contents($_FILES["home_image"]["name"]);
Here is my code that want to move the compressed image to my specific folder
move_uploaded_file($_FILES["home_image"]["tmp_name"][$i],"../../../Test/image/home_banner/" .$filename);
But the image that move to the folder is still remain the original size without compress.
Am I doing the mistake..?
I think move_uplodaded_file() is not appropriate here, because you change the uploaded file contents:
This function checks to ensure that the file designated by filename is
a valid upload file (meaning that it was uploaded via PHP's HTTP POST
upload mechanism). If the file is valid, it will be moved to the
filename given by destination.
Use rename() instead.
I'm also not 100% if you can edit the uploaded file directly..
I have a problem with php uploadify script.
I`m using single uploader, non multi.
Here is uploadify.php file which I edited:
<?php
// Callin
require_once("../../includes/functions.php");
connect_db();
check();
// If file exists
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
$targetFile = str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];
$ext = pathinfo($_FILES['Filedata']['name'], PATHINFO_EXTENSION); //figures out the extension
$newFileName = md5($tempFile).'.'.$ext; //generates random filename, then adds the file extension
$targetFile = str_replace('//','/',$targetPath) . $newFileName;
if($ext == "jpg" || $ext == "gif" || $ext == "png") {
$imgsize = getimagesize($targetFile);
switch(strtolower(substr($targetFile, -3)))
{
case "jpg":
$image = imagecreatefromjpeg($targetFile);
break;
case "png":
$image = imagecreatefrompng($targetFile);
break;
case "gif":
$image = imagecreatefromgif($targetFile);
break;
default:
exit;
break;
}
$width = 180;
$height = 135; // Don't need proportional
$src_w = $imgsize[0];
$src_h = $imgsize[1];
$picture = imagecreatetruecolor($width, $height);
imagealphablending($picture, false);
imagesavealpha($picture, true);
$bool = imagecopyresampled($picture, $image, 0, 0, 0, 0, $width, $height, $src_w, $src_h);
if($bool)
{
switch(strtolower(substr($targetFile, -3)))
{
case "jpg":
header("Content-Type: image/jpeg");
$bool2 = imagejpeg($picture,$targetPath."../../galleries/vthumbs/".$_FILES['Filedata']['name'],80); // Two folders back to public_html, and /galleries/vthumbs/
break;
case "png":
header("Content-Type: image/png");
imagepng($picture,$targetPath."../../galleries/vthumbs/".$_FILES['Filedata']['name']); // Two folders back to public_html, and /galleries/vthumbs/
break;
case "gif":
header("Content-Type: image/gif");
imagegif($picture,$targetPath."../../galleries/vthumbs/".$_FILES['Filedata']['name']); // Two folders back to public_html, and /galleries/vthumbs/
break;
}
}
imagedestroy($picture);
imagedestroy($image);
}
else {
// If extension isn't jpg or gif or png just move file
move_uploaded_file($tempFile,$targetFile);
}
echo '0'; // Required to trigger onComplete function
}
else { // Required to trigger onComplete function
echo '1'; // For tests
// mysql_query .........
}
?>
What I'm trying to make?
I want to make uploader which upload videos and images files.
If it's image I want to make just thumbnail. i don't care about full image, if isn't image file, that must be video and just upload video.
I thnik that php code works fine, uploadify script don't have callback errors from uploadify.php, but when I change if (!empty($_FILES)) to if (empty($_FILES)) page shows me 0. By this, I thnik that php code is OK, and there is no errors.
But files isn't uploaded. I checked for folder CHMODs and others. All is OK.
Script works with default uploadify.php code.
uploadify.php which I edited:
<?php
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
$targetFile = str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];
move_uploaded_file($tempFile,$targetFile);
echo '0'; // Required to trigger onComplete function
}
else { // Required to trigger onComplete
echo '1';
}
?>
If need, I will paste javascript code with I calling uploadify.php, but I Thnik that is no nessesary, because script works with default uploadify.php and with edited uploadify.php no.
All help is welcome...
Replace if (!empty($_FILES)) with if (sizeof($_FILES) > 0)