How to automatically resize uploaded photo in PHP? - php

How to auto resize the image uploaded to this foder: 'assets/media/':
<?php defined('SYSPATH') OR die('No direct access allowed.');
class Uploader_Controller extends Controller_Core {
public function bulkUpload() {
Kohana::log('debug', 'Start to upload');
$files = Validation::factory($_FILES)
->add_rules('picture', 'upload::valid', 'upload::required', 'upload::type[gif,jpg,png,jpeg]', 'upload::size[10M]');
Kohana::log('debug', 'Start to validate');
if ($files->validate()) {
Kohana::log('debug', 'validate passed');
$filename = upload::save('picture');
$thumbSize = Kohana::config('upload.thumb_size');
Image::factory($filename)
->resize($thumbSize[0], $thumbSize[1], Image::WIDTH)
->save(DOCROOT . 'assets/media/thumbs/' . basename($filename));
$partName = explode('/', $filename);
$picture = $partName[count($partName) - 1];
$data['name'] = '';
$data['picture'] = $picture;
$data['category_id'] = $this->input->post('category_id', 0);
$data['description'] = '';
;
$data['user_id'] = $this->input->post('user_id', 0);
$pictureModel = new Picture_Model();
try {
$photo = $pictureModel->savePicture($data);
echo url::site('assets/media/' . $picture);
} catch (Exception $e) {
}
}
}
}
i have add this line but still not working:
$filename->resizeToWidth(300);

You are not using the Kohana image and upload library properly. The docs have some examples on how to use the Kohana image upload and resize library:
Upload and resize
Cropping Profile Images
Docs on how to use the image library
You can resize and save an image with to following code:
Image::factory($filename)
->resize(300, NULL, Image::AUTO)
->save($your_save_path);

Related

Image Intervention does not save resized images

I'm working with Laravel 9 and Image Intervention 2.7 and I wanted to resize uploaded images.
Here is the upload method:
public static function upload($file,$cat,$queid)
{
...
if (in_array($file->getClientOriginalExtension(), self::resizeable())) {
$file->storeAs(self::route(), $fileName);
$custom = self::resize($file, $fileName);
}
$file->storeAs(self::route(), $fileName);
...
}
So I call the static function reszie which goes here:
public static function resize($file, $fileName)
{
$path = self::route();
foreach (self::size() as $key => $value) {
$resizePath = self::route() . "{$value[0]}x{$value[1]}_" . $fileName;
Image::make($file->getRealPath())
->resize($value[0], $value[1], function ($constraint) {
$constraint->aspectRatio();
})
->save($resizePath);
$urlResizeImage[] = ["upf_path" => $resizePath, "upf_dimension" => "{$value[0]}x{$value[1]}"];
}
self::$urlResizeImage = $urlResizeImage;
}
As you can see I pass the $resizePath as $path to save method of Image Intervention Facade:
public function save($path = null, $quality = null, $format = null)
{
$path = is_null($path) ? $this->basePath() : $path;
if (is_null($path)) {
throw new NotWritableException(
"Can't write to undefined path."
);
}
if ($format === null) {
$format = pathinfo($path, PATHINFO_EXTENSION);
}
$data = $this->encode($format, $quality);
$saved = #file_put_contents($path, $data);
if ($saved === false) {
throw new NotWritableException(
"Can't write image data to path ({$path})"
);
}
// set new file info
$this->setFileInfoFromPath($path);
return $this;
}
But now the problem is with file_put_contents which does not generate the resized images.
And also no errors returned and just the original image will be saved!
So what's going wrong here? How can I properly resize the original image and save it to the directory?
I would really appreciate any idea or suggestion from you guys about this...

how to prevent imagecreatefrom from creating a static gif - PHP

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);
}
?>

Issue when uploading image to tmp folder, resize and then upload to S3 bucket

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.

Generate thumbnail image from video in codeigniter

i want to generate the thumbnail image from the uploaded video but the problem is that the thumbnail image is not generating. The uploaded video goes to the uploads folder but at this place the image is not generating..Please look at the code, and tell me where i am wrong.
public function add_video() { // move_upload_file code
if(!empty($_FILES['video']['name'])){
$tmp_name_array = $_FILES['video']['tmp_name'];
$n_array = $_FILES['video']['name'];
$exp = explode('.', $n_array);
$newnme = date('his').rand().'.'.end($exp);
$raw_name = explode('.', $newnme);
$full_path = base_url('uploads').'/'.$newnme;
$new_path = base_url('uploads').'/';
if(move_uploaded_file($tmp_name_array, "uploads/".$newnme))
{
$full_path = base_url('uploads').'/'.$newnme;
$new_path = base_url('uploads').'/';
print_r(exec("ffmpeg -i ".$full_path." ".$new_path.$raw_name[0].".jpg"));
echo "uploaded Successfully";
}
}else{
echo "not selected any file";
}
}

API upload image from ionic to laravel back end

so i'm trying to upload image from ionic app to laravel web application problem it is i don't know how to do this my controller looks like this
public function postDamage(Request $request){
try{
$damage = new damage();
$damage->type = $request->input('type');
$damage->address = $request->input('address');
$damage->description = $request->input('description');
$damage->solvedBy = $request->input('solvedBy');
$damage->userToken = $request->input('userToken');
$damage->opstina = $request->input('opstina');
$damage->image = $request->input('image');
/* $imgName="";
if ($request->hasFile('image')) {
$imgName = time().'.'.$image->getClientOriginalExtension();
$destinationPath = public_path('/images');
$image->move($destinationPath, $imgName);
$this->save();
return back()->with('success','Image Upload successfully');
}
$target_path = time().'.jpg';
$imagedata = $request->input('image');
$imagedata = str_replace('data:image/jpeg;base64,',$imagedata);
$imagedata = str_replace('data:image/jpg;base64,',$imagedata);
$imagedata = str_replace(' ', '+',$imagedata);
$imagedata = base64_decode($imagedata);
file_put_contents($target_path,$imagedata);
$damage->image = $imagedata; */
$damage->save();
return response()->json(['response'=>'Штетата е пратено.']);
}catch (\Exception $e){
return response()->json(['response'=>$e->getMessage()]);
}
}
now how i can post some data together with image but image to be uploaded in server. The image that is generated in ionic it is in base64.
Any method i tried from google but none of them works.
Thank you.
I am using Spatie Laravel Medialibrary to save images for my laravel models here is a git link:
https://github.com/spatie/laravel-medialibrary
then in controller
if ($f = $request->file) {
$img = explode(",", $f)[1];
$base64data = str_replace(',', '', $img);
$item->addMediaFromBase64($base64data)
->usingFileName('original.jpg')
->toMediaCollection('item');
}
now in your case that might be (not tested)
$img = explode(",", $f)[1];
$base64data = str_replace(',', '', $img);
$imagedata = base64_decode($base64data);
file_put_contents($target_path,$imagedata);

Categories