Cannot optimize image in PHP - php

This is the code I have:
$from = ...; // original uploaded file
$target = ...; // save path for optimized file
#unlink($target); // removes file if already exists
$image_o = imagecreatefromjpeg($from); // get a file
imagejpeg($image_o, $target, 85); // save optimized
imagedestroy($image_o); // free memory
But it doesn't do anything. This is going in loop, but now I test it on the single file. Seems to be working on smaller files. I tried image with size ~120 kB and optimized OK. But file with more than 1 MB, it will do nothing and those are files I really need to optimize. I also tried this:
set_time_limit(6000);
ini_set('memory_limit', '200M');
But no help. I'm working on a shared hosting, so I have no access to the php.ini or to install 3rd party PHP extension. Is there an alternative for imagecreatefromjpeg which seems to be the problem?

Related

Codeigniter force_download fails on large Zip files

When using force_download to download a zip file my code works for a zip file that is 268Mb (31 MP3 files) but not for a zip file that is 287Mb (32 MP3 files), the difference being 1 extra MP3 file added to the zip. The download attempts to start and appears as though it keeps starting over and over a couple of times and shows as failed with Chrome indicating that the zip file is incomplete. Windows reports the zip file which is only 61Kb is invalid when trying to open it.
The zip file gets created and MP3 files added to it by another area of code.
I have increased the memory_limit up to 1024M but its no different.
Below is the code I want working:
$this->load->helper("download");
$lastbasket = "uniquefilename.zip";
$zipdlpath = base_url()."uploads/zipped/".$lastbasket;
$fileContent = file_get_contents($zipdlpath);
force_download($lastbasket, $fileContent);
I have also tried using the following code:
$this->load->helper("download");
$lastbasket = "uniquefilename.zip";
$zipdlpath = FCPATH."uploads/zipped/".$lastbasket;
force_download($zipdlpath, NULL);
Providing a direct link to the zip file works fine (so I know the issue isnt with the zip file itself) but the force_download function in the controller appears to have an issue with larger files or is there a setting I am missing somewhere that is forcing a limit somehow?
PHP 7.1.33
CodeIgniter 3.1.9
Try to increase memory limit by adding this code:
ini_set('memory_limit','1024M');
increase memory limit and use fopen, fread
try this
$this->load->helper("download");
$lastbasket = "uniquefilename.zip";
$zipdlpath = FCPATH."uploads/zipped/".$lastbasket;
force_download($zipdlpath, NULL);
if (is_file($zipdlpath))
{
$chunkSize = 1024 * 1024;
$handle = fopen($zipdlpath, 'rb');
while (!feof($handle))
{
$buffer = fread($handle, $chunkSize);
echo $buffer;
ob_flush();
flush();
}
fclose($handle);
exit;
}
I've tried with the following custom download helper, may it will work for you.
Ref Link - https://github.com/bcit-ci/CodeIgniter/wiki/Download-helper-for-large-files

eajaxupload for Yii always "failed"

We are currently trying to use the extension eajaxupload for Yii but it seems to be outputting failed everytime we try to upload a file.
We have tried
a) editing the file / minimum file sizes
b) playing around with the file path (may still be incorrect, if anyone knows what the path for locally using in xampp would be, let us know. Our uploads folder is in the root of the project.)
c) changing the htiaccess php file
d) permissions
we just don't know if the code itself is appearing wrong.
controller
/* UPLOADER */
public function actionUpload(){
Yii::import("ext.EAjaxUpload.qqFileUploader");
// $folder = '/uploads/';
// $folder=Yii::getPathOfAlias() .'/upload/';
$folder=Yii::app()->baseUrl . '/uploads/';
$allowedExtensions = array("jpg","png");//array("jpg","jpeg","gif","exe","mov" and etc...
$sizeLimit = 10 * 1024 * 1024;// maximum file size in bytes
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
$result = $uploader->handleUpload($folder);
// $return = htmlspecialchars(json_encode($result), ENT_NOQUOTES);
//
// $fileSize=filesize($folder.$result['filename']);//GETTING FILE SIZE
// $fileName=$result['filename'];//GETTING FILE NAME
//
// echo $return;// it's array
$result = $uploader->handleUpload($folder);
$fileSize=filesize($folder.$result['filename']);//GETTING FILE SIZE
$fileName=$result['filename'];//GETTING FILE NAME
$result=htmlspecialchars(json_encode($result), ENT_NOQUOTES);
echo $result;// it's array
}
View
*$this->widget('ext.EAjaxUpload.EAjaxUpload',
array(
'id'=>'uploadFile',
'config'=>array(
'action'=>'/upload/',
// 'action'=>Yii::app()->createUrl('controllers/uploads/'),
'allowedExtensions'=>array("jpg","png"),//array("jpg","jpeg","gif","exe","mov" and etc...
'sizeLimit'=>10*1024*1024,// maximum file size in bytes
//'minSizeLimit'=>10*1024*1024,// minimum file size in bytes
'onComplete'=>"js:function(id, fileName, responseJSON){ alert(fileName); }",
'messages'=>array(
'typeError'=>"{file} has invalid extension. Only {extensions} are allowed.",
'sizeError'=>"{file} is too large, maximum file size is {sizeLimit}.",
'minSizeError'=>"{file} is too small, minimum file size is {minSizeLimit}.",
'emptyError'=>"{file} is empty, please select files again without it.",
'onLeave'=>"The files are being uploaded, if you leave now the upload will be cancelled."
),
'showMessage'=>"js:function(message){ alert(message); }"
)*
I got the same problem long ago.
You have to make sure that:
you get the local path, not url (Yii::getPathOfAlias('webroot')).
the $sizeLimit has to be less than the php options 'post_max_size' and 'upload_max_size'. You can check their values with ini_get(variable) and convert it to Bytes.
Also noticed that you are trying to upload the file twice.
If none of them work post the error message that you are getting.
It seems to me that your action is wrong in the
'config'=>array(
'action'=>'/upload/',
If you are uploading to the public function actionUpload()
then your action must be 'upload/upload' because the ConrollerName/ActionName must match the 'action' in your widget
'config'=>array(
'action'=> Yii::app()->baseUrl . '/upload/upload',
or
'config'=>array(
'action'=>$this->createUrl('upload/upload')
Take a look at this too: http://www.yiiframework.com/doc/guide/1.1/en/topics.url
Good luck
To update this, it wouldn't work on local server Xampp on MAC.
It worked on our live dev server, but not the live server. Seems the extension is server dependant. There is a lack of documentation and I imagine there is a fix, but it answers a lot of questions how the code is fine but not working.

PHP DropboxUploader.php does not work for huge files

I have the following PHP code that lets me back up files to Dropbox:
// Dropbox username/password
$dropbox_email = 'xxxxxxxxxx';
$dropbox_pass = 'xxxxxxxxxxx';
include('DropboxUploader.php');
$uploader = new DropboxUploader($dropbox_email, $dropbox_pass);
$uploader->upload('backup-images.php','Backup/');
$uploader->upload($zipArchiveName,'Backup/');
File backup-images.php is around 1kb while $zipArchiveName is around 400Mb. I seem to mange to upload backup-images.php but not $zipArchiveName.
I tried using
ini_set('max_execution_time', 0);
ini_set('memory_limit', '-1');
I also tried modifying php.ini i.e. max_execution_time and the memory_limit but I can't seem to upload the huge file to dropbox. I have ample of space on my dropbox account.
In my case I donot wish to use the Dropbox SDK but DropboxUploader.php found here.
I'd like suggestions or reasons why this isn't working or ideas how to get around it.
One way you can go around this issue by splitting your backup file into multiple files. TAR archiver has a way to create multi-part archives. Take a look: https://unix.stackexchange.com/questions/21373/can-i-automate-tars-multi-volume-feature
There is a constant in that class that provides upload size limit at this line:
const DROPBOX_UPLOAD_LIMIT_IN_BYTES = 314572800;
This is 300MB. So this class should throw an Exception in the following portion of code for a 400MB file:
$filesize = filesize($source);
if ($filesize < 0 or $filesize > self::DROPBOX_UPLOAD_LIMIT_IN_BYTES) {
throw new Exception("File '$source' too large ($filesize bytes).", self::CODE_FILESIZE_TOO_LARGE);
}
Are you not seeing this this Exception in error logs?
I don't know if that is the true current limit for this Dropbox API. You may want to check their documentation to see if you can bump up the max size constant.

Resize image directly from Rackspace Cloud Files 'object' without downloading?

I have moved my images to Rackspace Cloud Files and am using their PHP API. I am trying to do the following:
Get an image from my "originals" container
Resize it, sharpen it, etc.
Save the resized image to the "thumbs" container
My problem is with #2. I was hoping to resize without having to copy the original to my server first (since the images are large and I'd like to resize dynamically), but can't figure out how. This is what I have so far (not much):
$container = $conn->get_container("originals");
$obj = $container->get_object("example.jpg");
$img = $obj->read();
Part of the problem is I don't fully understand what is being returned by the read() function. I know $img contains the object's "data" (which I was able to print out as gibberish), but it is neither a file nor a url nor an image resource, so I don't know how to deal with it. Is it possible to convert $img into an image resource somehow? I tried imagecreatefromjpeg($img) but that didn't work.
Thanks!
First, you cannot resize an image without loading it into memory. Unless the remote server offers some "resize my image for me, here are the parameters" API, you have to load the image in your script to manipulate it. So you'll have to copy the file from the CloudFiles container to your server, manipulate it, then send it back into storage.
The data you receive from $obj->read() is the image data. That is the file. It doesn't have a file name and it's not saved on the hard disk, but it is the entire file. To load this into gd to manipulate it, you can use imagecreatefromstring. That's analogous to using, for example, imagecreatefrompng, only that imagecreatefrompng wants to read a file from the file system by itself, while imagecreatefromstring just accepts the data that you have already loaded into memory.
You can try to dump the content of the $img variable into a writable file as per the below:
<?php
$filename = 'modifiedImage.jpg';
/*
* 'w+' Open for reading and writing; place the file pointer at the beginning of the file and truncate
* the file to zero length. If the file does not exist, attempt to create it.
*/
$handle = fopen($filename, 'w+');
// Write $img to the opened\created file.
if (fwrite($handle, $img) === FALSE) {
echo "Cannot write to file ($filename)";
exit;
}
echo "Success, wrote to file ($filename)";
fclose($handle);
?>
More details:
http://www.php.net/manual/en/function.fopen.php
http://www.php.net/manual/en/function.fwrite.php
Edit:
You might also want to double check the type of data returned by the read() function, because if the data is not a jpg image, if it's for example a png, the extension of the file needs to be changed accordingly.

PHP filesize reporting old size

The following code is part of a PHP web-service I've written. It takes some uploaded Base64 data, decodes it, and appends it to a file. This all works fine.
The problem is that when I read the file size after the append operation I get the size the file was before the append operation.
$fileOut = fopen($filepath.$filename, "ab")
fwrite($fileOut, base64_decode($data));
fflush($fileOut);
fclose($fileOut);
$newSize = filesize($filepath.$filename); // gives old file size
What am I doing wrong?
System is:
PHP 5.2.14
Apache 2.2.16
Linux kernel 2.6.18
On Linux based systems, data fetched by filesize() is "statcached".
Try calling clearstatcache(); before the filesize call.
According to the PHP manual:
The results of this function are
cached. See clearstatcache() for more
details.
http://us2.php.net/manual/en/function.filesize.php
Basically, you have to clear the stat cache after the file operation:
$fileOut = fopen($filepath.$filename, "ab")
fwrite($fileOut, base64_decode($data));
fflush($fileOut);
fclose($fileOut);
clearstatcache();
$newSize = filesize($filepath.$filename);
PHP stores all file metadata it reads in a cache, so it's likely that the file size is already stored in that cache, and you need to clear it. See clearstatcache and call it before you call filesize.

Categories