Can anybody tell me how I can solve the following issue:
include('php/resizeImage.php');
if($_POST['uploadlink']){
$url = $_POST['uploadlink'];
$urlImage = file_get_contents($url);
if ($_POST['filename']){
$filename = $_POST['filename'].".jpg";
} else {
$urlinfo = parse_url($url);
$filename = basename($urlinfo['path']);
}
$image = new ResizeImage();
$image->load($filename);
$image->resizeToWidth(300);
$image->save($filename);
file_put_contents("images/upload/".$filename, $urlImage);
}
After I have received the image data from file_get_contents from a URL I want to resize it through my resizeImage script which takes the filename of the image as a parameter.
Edit: ResizeImage function load and resizeToWidth:
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
if( $this->image_type == IMAGETYPE_JPEG ) {
$this->image = imagecreatefromjpeg($filename);
} elseif( $this->image_type == IMAGETYPE_GIF ) {
$this->image = imagecreatefromgif($filename);
} elseif( $this->image_type == IMAGETYPE_PNG ) {
$this->image = imagecreatefrompng($filename);
}
}
function resizeToWidth($width) {
$ratio = $width / $this->getWidth();
$height = $this->getheight() * $ratio;
$this->resize($width,$height);
}
I have no trouble doing it when the user selects a local image through input type='file'.
if (isset($_FILES["uploadedfile"])){
$ufilename = $_FILES["uploadedfile"]["name"];
$ufiletmpname = $_FILES["uploadedfile"]["tmp_name"];
$image = new ResizeImage();
$image->load($ufiletmpname);
$image->resizeToWidth(300);
$image->save($ufiletmpname);
}
Another problem:
I forward the name of the user to my script because I want to create an individual folder for each user, so they only can see their own uploaded images.
$admin = $_GET['admin'];
file_put_contents("images/upload/".$admin."/".$filename, $urlImage);
Why is this not working for me?
Thanks.
Easy.
Just alter the code of whatever yours ResizeImage class to make it able to operate the image binary contents in addition to filename.
Your second question is quite simple too.
Setup your PHP installation to make it display errors on the screen (for the development server, of course!) and you will see the exact answer to your question, "Why is this not working for me?".
error_reporting(E_ALL);
ini_set('display_errors',1);
usually helps.
(also be sure your code do not do any HTTP redirects which may conceal the error messages from you)
What's ResizeImage?
If it were me, I'd do:
$data = file_get_contents($name);
$image = imagecreatefromstring($data);
// resize the image
For your first question, the ResizeImage is your own class, or something you downloaded from the net. To help you, we need to see it.
For the second part, file_put_contents won't create directories to you, to do that, you need to use the mkdir function.
Related
I am facing a weird problem. If I upload an image using PHP and my uploaded image got broken or half uploaded randomly. So the image appears like this on the server:
Moreover, I am just using the ajax post method and send an image within the formdata to the PHP backend.
var formData = new FormData();
formData.append('loop_logo', $('.loop_logo_public')[0].files[0]);
var image = $('.loop_logo_public')[0].files[0];
var fsize = image.size;
formData.append('file_size',fsize);
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
return xhr;
},
method: 'post',
url: mainurl + 'api.php?type=create_post',
contentType: false,
processData: false,
data: formData
}).done(function(data) {
//other actions
});
as per this Handle android half uploaded/broken uploaded images to server I have validated the filesize from before upload and after upload also. There is no change in file size at all.
here is my backend code for file upload.
$mainurl="https://example.com/";
class SimpleImage {
var $image;
var $image_type;
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
if( $this->image_type == IMAGETYPE_JPEG ) {
$this->image = imagecreatefromjpeg($filename);
} elseif( $this->image_type == IMAGETYPE_GIF ) {
$this->image = imagecreatefromgif($filename);
} elseif( $this->image_type == IMAGETYPE_PNG ) {
$this->image = imagecreatefrompng($filename);
}
}
function save($filename, $image_type=IMAGETYPE_JPEG, $compression=100, $permissions=null) {
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image,$filename,$compression);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image,$filename);
} elseif( $image_type == IMAGETYPE_PNG ) {
imagepng($this->image,$filename);
}
if( $permissions != null) {
chmod($filename,$permissions);
}
return true;
}
}
function uploadFile($file, $name)
{
$target = basename($file["name"]);
$imageFileType = strtolower(pathinfo($target,PATHINFO_EXTENSION));
$dest = $mainurl."uploads/".$name.".".$imageFileType;
$dest2 = "uploads/".$name.".".$imageFileType;
if($imageFileType == "jpg" || $imageFileType == "png" || $imageFileType == "jpeg" || $imageFileType == "gif")
{
$image = new SimpleImage();
$image->load($file["tmp_name"]);
$image_info = getimagesize($file["tmp_name"]);
$image_type = $image_info[2];
if($image->save($dest2,$image_type,100))
{
return "uploads/".$name.".".$imageFileType;
}
else{
if(#move_uploaded_file($file["tmp_name"], $dest)){
return "uploads/".$name.".".$imageFileType;
}else{
return '';
}
}
}
}else{
return '';
}
}
if (isset($_FILES['loop_logo'])) {
$backsize = $_FILES['loop_logo']['size'];
$rsize = $_POST['file_size'];
if ($rsize == $backsize) {
$loop_logo = uploadFile($_FILES['loop_logo'], rand(9999, 9999999).time(), $mainurl);
}
} else {
$loop_logo = '';
}
I have followed one of this solution Resize image in PHP for file upload with imagecreatefromjpeg and imagejpeg and tried normal #move_uploaded_file also both are having the same results.
My server is Ubuntu 20.04 LTS and I am using PHP v8.0.3 (FPM), Apache (Apache/2.4.41).
I am having cloudflare CDN also, I have disabled that and tried still the same.
Finally, I have checked the error log in apache nothing is related to any image or upload problem at all.
I am having plenty of space in my server and tmp folder (15 GB) and having 2.6 GB free Ram also.
I don't know what exactly causing the issue. Thanks in advance
I have found the bug and I am closing this question.
$filePath=$post['post_image'];
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;
}
$path_parts = pathinfo($filePath);
$new_file_name="uploads/".$path_parts['filename'].".jpg";
convertImage($filePath,$new_file_name,40);
We have a separate post page and in that individual page, we are having an above function to compress the image for meta og:image. In that function, we missed one logic that is to create a new compressed version and save it separately. However, we forget to implement that. Therefore, after the compress, it has replaced the existing file. Due to the quality was set to 40 image was broken in half.
Why this has happened randomly?
Because, whenever someone trying to post that particular page in social media, the above function convertImage got triggered as well as we have opened that page manually also triggered the same.
Solution
We have increased the quality to 100 here convertImage($filePath,$new_file_name,100); and saved the minified version with new name $new_file_name="uploads/".$path_parts['filename']."-min.jpg"; solved my problem.
I have a function that uploads files up to 8MB but now I also want to compress or at least rescale larger images, so my output image won't be any bigger than 100-200 KB and 1000x1000px resolution. How can I implement compress and rescale (proportional) in my function?
function uploadFile($file, $file_restrictions = '', $user_id, $sub_folder = '') {
global $path_app;
$new_file_name = generateRandomString(20);
if($sub_folder != '') {
if(!file_exists('media/'.$user_id.'/'.$sub_folder.'/')) {
mkdir('media/'.$user_id.'/'.$sub_folder, 0777);
}
$sub_folder = $sub_folder.'/';
}
else {
$sub_folder = '';
}
$uploadDir = 'media/'.$user_id.'/'.$sub_folder;
$uploadDirO = 'media/'.$user_id.'/'.$sub_folder;
$finalDir = $path_app.'/media/'.$user_id.'/'.$sub_folder;
$fileExt = explode(".", basename($file['name']));
$uploadExt = $fileExt[count($fileExt) - 1];
$uploadName = $new_file_name.'_cache.'.$uploadExt;
$uploadDir = $uploadDir.$uploadName;
$restriction_ok = true;
if(!empty($file_restrictions)) {
if(strpos($file_restrictions, $uploadExt) === false) {
$restriction_ok = false;
}
}
if($restriction_ok == false) {
return '';
}
else {
if(move_uploaded_file($file['tmp_name'], $uploadDir)) {
$image_info = getimagesize($uploadDir);
$image_width = $image_info[0];
$image_height = $image_info[1];
if($file['size'] > 8000000) {
unlink($uploadDir);
return '';
}
else {
$finalUploadName = $new_file_name.'.'.$uploadExt;
rename($uploadDirO.$uploadName, $uploadDirO.$finalUploadName);
return $finalDir.$finalUploadName;
}
}
else {
return '';
}
}
}
For the rescaling I use a function like this:
function dimensions($width,$height,$maxWidth,$maxHeight)
// given maximum dimensions this tries to fill that as best as possible
{
// get new sizes
if ($width > $maxWidth) {
$height = Round($maxWidth*$height/$width);
$width = $maxWidth;
}
if ($height > $maxHeight) {
$width = Round($maxHeight*$width/$height);
$height = $maxHeight;
}
// return array with new size
return array('width' => $width,'height' => $height);
}
The compression is done by a PHP function:
// set limits
$maxWidth = 1000;
$maxHeight = 1000;
// read source
$source = imagecreatefromjpeg($originalImageFile);
// get the possible dimensions of destination and extract
$dims = dimensions(imagesx($source),imagesy($source),$maxWidth,$maxHeight);
// prepare destination
$dest = imagecreatetruecolor($dims['width'],$dims['height']);
// copy in high-quality
imagecopyresampled($dest,$source,0,0,0,0,
$width,$height,imagesx($source),imagesy($source));
// save file
imagejpeg($dest,$destinationImageFile,85);
// clear both copies from memory
imagedestroy($source);
imagedestroy($dest);
You will have to supply $originalImageFile and $destinationImageFile. This stuff comes from a class I use, so I edited it quite a lot, but the basic functionality is there. I left out any error checking, so you still need to add that. Note that the 85 in imagejpeg() denotes the amount of compression.
you can use a simple one line solution through imagemagic library the command will like this
$image="path to image";
$res="option to resize"; i.e 25% small , 50% small or anything else
exec("convert ".$image." -resize ".$res." ".$image);
with this you can rotate resize and many other image customization
Take a look on imagecopyresampled(), There is also a example that how to implement it, For compression take a look on imagejpeg() the third parameter helps to set quality of the image, 100 means (best quality, biggest file) and if you skip the last option then default quality is 75 which is good and compress it.
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.
So, I have this class that's half-working.
Somehow I'm not being able to copy a re-sized sample of the uploaded image, only a black "square" with the "correct" dimensions (screw the dimensions, as long as the thumb comes up clear. one step at the time).
I'm sorry for the WOT but it's driving me cray-cray.
Thanks in advance.
<?php
class Upload {
#function from http://stackoverflow.com/a/10666106/587811
public function resize_values($origWidth,$origHeight,$maxWidth = 200,$maxHeight = 200){
#check for longest side, we'll be seeing that to the max value above
if($origHeight > $origWidth){ #if height is more than width
$newWidth = ($maxHeight * $origWidth) / $origHeight;
$retval = array(width => $newWidth, height => $maxHeight);
}
else{
$newHeight= ($maxWidth * $origHeight) / $origWidth;
$retval = array(width => $origWidth, height => $newHeight);
}
return $retval;
}
public function image($picurl, $file, $path="images/uploaded/") {
echo "function chamada!";
if ($picurl) {
$picFileName=rand(1,9999).$_SESSION['id'];
$picExt=substr(strstr($picurl,'.'),1,3);
$picExt=strtolower($picExt);
$allowed = array("jpg","png","gif","bmp");
if (in_array($picExt,$allowed)) {
if (getimagesize($file)) {
$picNewName=str_replace(" ","_",$picFileName.'.'.$picExt);
$picWhereTo=$path.$picNewName;
$copy=move_uploaded_file($file, $picWhereTo);
if ($copy) {
list($width, $height) = getimagesize($picWhereTo);
$size = $this->resize_values($width,$height,250,250);
$thumb = imagecreatetruecolor($size['width'],$size['height']);
imagealphablending($thumb, false);
$source = imagecreatefromjpeg($picWhereTo);
imagecopyresized($thumb,$source,0,0,0,0,$size['width'],$size['height'],$width,$height);
$picNewName=$picFileName.'_thumb.'.$picExt;
imagejpeg($thumb,$path.$picNewName);
$picinfo['where']=$picWhereTo;
$picinfo['name']=$picNewName;
return $picinfo;
}
else return false;
}
else return false;
}
else return false;
}
}
}
?>
I've ran into a similar problem like this. This has to do with png's with transparency.
Give this a shot after you create $thumb using imagecreatetruecolor();
imagealphablending($thumb, false);
I'm not entirely certain this is the solution - but I think its along the right track. Your true color supports alpha blending - and it is blending in the background from the jpeg - and it might be confused by the lack of information.
If this doesn't work, please describe the exact image format you are uploading so we can try it out and see what happens.
Change your
$source = imagecreatefromjpeg($file);
to
$source = imagecreatefromjpeg($picWhereTo);
And this is how you call the function
$objoflclass->image($_FILES['img']['name'],$_FILES['img']['tmp_name'],'');
where $_FILES['img'] is the name of the image upload field and i believe from this u can understand what was the problem
I've created an image class to display and convert images on the site with GD library. when I want to show jpeg images without any HTML code in the site
everything will be OK because I set header('Content-Type: image/jpeg').
My code is like below:
$filepath = 'path to the image file';
$info = getimagesize( $filepath );
$this->type = $info[2];
if( $this->type == IMAGETYPE_JPEG )
{
$this->image = imagecreatefromjpeg($filepath); // set the resource image
}
if( $this->type == IMAGETYPE_JPEG )
{
$type = 'image/jpeg';
}
header('Content-Type: ' . $type );
if( $this->type == IMAGETYPE_JPEG )
{
imagejpeg( $this->image );
}
This code works perfectly, but how should I show images if I want to show them inside HTML codes (ob_start did not work).
Request that script from a different file like any regular image:
<img src="path/to/the/file/that/outputs/the/image.php">