PHP Imagick resize with black background - php

I am writing a PHP script using the imagick extension. What I want the script to do is take an image a user uploads, and create a 200x128 thumbnail out of it.
That's not the only thing. Obviously, not all images will fit the aspect ratio of 200x128. So what I want the script to do is fill in gaps with a black background.
Right now, the image resizes, but there is no black background and the size isn't correct. Basically, the image should ALWAYS be 200x128. The resized image will go in the center, and the rest of the contents will be filled with black.
Any ideas?
Here's my code:
function portfolio_image_search_resize($image) {
// Check if imagick is loaded. If not, return false.
if(!extension_loaded('imagick')) { return false; }
// Set the dimensions of the search result thumbnail
$search_thumb_width = 200;
$search_thumb_height = 128;
// Instantiate class. Then, read the image.
$IM = new Imagick();
$IM->readImage($image);
// Obtain image height and width
$image_height = $IM->getImageHeight();
$image_width = $IM->getImageWidth();
// Determine if the picture is portrait or landscape
$orientation = ($image_height > $image_width) ? 'portrait' : 'landscape';
// Set compression and file type
$IM->setImageCompression(Imagick::COMPRESSION_JPEG);
$IM->setImageCompressionQuality(100);
$IM->setResolution(72,72);
$IM->setImageFormat('jpg');
switch($orientation) {
case 'portrait':
// Since the image must maintain its aspect ratio, the rest of the image must appear as black
$IM->setImageBackgroundColor("black");
$IM->scaleImage(0, $search_thumb_height);
$filename = 'user_search_thumbnail.jpg';
// Write the image
if($IM->writeImage($filename) == true) {
return true;
}
else {
return false;
}
break;
case 'landscape':
// The aspect ratio of the image might not match the search result thumbnail (1.5625)
$IM->setImageBackgroundColor("black");
$calc_image_rsz_height = ($image_height / $image_width) * $search_thumb_width;
if($calc_image_rsz_height > $search_thumb_height) {
$IM->scaleImage(0, $search_thumb_height);
}
else {
$IM->scaleImage($search_thumb_width, 0);
}
$filename = 'user_search_thumbnail.jpg';
if($IM->writeImage($filename) == true) {
return true;
}
else {
return false;
}
break;
}
}

I know its old but I found the answer after long trying:
you need to use thumbnailimage
(http://php.net/manual/en/imagick.thumbnailimage.php)
with both $bestfit and $fill as true like so:
$image->thumbnailImage(200, 128,true,true);

exec('convert -define jpeg:size=400x436 big_image.jpg -auto-orient -thumbnail 200x218 -unsharp 0x.5 thumbnail.gif');
You'll need to install imagemagick.
sudo apt-get install imagemagick
Take a look at:
http://www.imagemagick.org/Usage/thumbnails/#creation
It shows further examples and how to pad out the thumbnail with a background color of your choice.

Related

How to install small PHP scripts for tools into pages of an existing website?

First of all, I'm a physician and not a technical expert whatsoever like you, so please bear with me :D
I want to build a website that offers online tools like "email extracting", "image resizing", etc, and I was wondering how to install tools with small PHP scripts like 1-2 .php files, and have them on different pages in the existing website "internettoolkits.com"?
Other tools I found, have more folders and files and most videos talk about databases and playing with file managers, and for those, I decided to create a subdomain for each, following the advises of creating new database and updating the file manager since they have an admin and user areas. (according to my understanding)
But for the small ones that don't require admin and user areas, like email extracting tool, can I have the php scripts added to a page/post in wordpress like with using HTML scripts? I tried the HTML scripts and they work fine (you can see examples on that website)
Do I insert them in specific files in the file manager and how to do it to make it appear in a designated page called "Thumbnail Generator Tool" for example?
Do I need to create a specific database for each of those small tools or not?
I tried using plugins (code snippet) and (insert PHP code snippet) and both didn't work
Example of tool to have: Thumbnail generator tool that have 2 files below:
first file (image.class.php)
<?php
###############################################################
# Thumbnail Image Class for Thumbnail Generator
###############################################################
# For updates visit http://www.zubrag.com/scripts/
###############################################################
class Zubrag_image {
var $save_to_file = true;
var $image_type = -1;
var $quality = 100;
var $max_x = 100;
var $max_y = 100;
var $cut_x = 0;
var $cut_y = 0;
function SaveImage($im, $filename) {
$res = null;
// ImageGIF is not included into some GD2 releases, so it might not work
// output png if gifs are not supported
if(($this->image_type == 1) && !function_exists('imagegif')) $this->image_type = 3;
switch ($this->image_type) {
case 1:
if ($this->save_to_file) {
$res = ImageGIF($im,$filename);
}
else {
header("Content-type: image/gif");
$res = ImageGIF($im);
}
break;
case 2:
if ($this->save_to_file) {
$res = ImageJPEG($im,$filename,$this->quality);
}
else {
header("Content-type: image/jpeg");
$res = ImageJPEG($im, NULL, $this->quality);
}
break;
case 3:
if (PHP_VERSION >= '5.1.2') {
// Convert to PNG quality.
// PNG quality: 0 (best quality, bigger file) to 9 (worst quality, smaller file)
$quality = 9 - min( round($this->quality / 10), 9 );
if ($this->save_to_file) {
$res = ImagePNG($im, $filename, $quality);
}
else {
header("Content-type: image/png");
$res = ImagePNG($im, NULL, $quality);
}
}
else {
if ($this->save_to_file) {
$res = ImagePNG($im, $filename);
}
else {
header("Content-type: image/png");
$res = ImagePNG($im);
}
}
break;
}
return $res;
}
function ImageCreateFromType($type,$filename) {
$im = null;
switch ($type) {
case 1:
$im = ImageCreateFromGif($filename);
break;
case 2:
$im = ImageCreateFromJpeg($filename);
break;
case 3:
$im = ImageCreateFromPNG($filename);
break;
}
return $im;
}
// generate thumb from image and save it
function GenerateThumbFile($from_name, $to_name) {
// if src is URL then download file first
$temp = false;
if (substr($from_name,0,7) == 'http://') {
$tmpfname = tempnam("tmp/", "TmP-");
$temp = #fopen($tmpfname, "w");
if ($temp) {
#fwrite($temp, #file_get_contents($from_name)) or die("Cannot download image");
#fclose($temp);
$from_name = $tmpfname;
}
else {
die("Cannot create temp file");
}
}
// check if file exists
if (!file_exists($from_name)) die("Source image does not exist!");
// get source image size (width/height/type)
// orig_img_type 1 = GIF, 2 = JPG, 3 = PNG
list($orig_x, $orig_y, $orig_img_type, $img_sizes) = #GetImageSize($from_name);
// cut image if specified by user
if ($this->cut_x > 0) $orig_x = min($this->cut_x, $orig_x);
if ($this->cut_y > 0) $orig_y = min($this->cut_y, $orig_y);
// should we override thumb image type?
$this->image_type = ($this->image_type != -1 ? $this->image_type : $orig_img_type);
// check for allowed image types
if ($orig_img_type < 1 or $orig_img_type > 3) die("Image type not supported");
if ($orig_x > $this->max_x or $orig_y > $this->max_y) {
// resize
$per_x = $orig_x / $this->max_x;
$per_y = $orig_y / $this->max_y;
if ($per_y > $per_x) {
$this->max_x = $orig_x / $per_y;
}
else {
$this->max_y = $orig_y / $per_x;
}
}
else {
// keep original sizes, i.e. just copy
if ($this->save_to_file) {
#copy($from_name, $to_name);
}
else {
switch ($this->image_type) {
case 1:
header("Content-type: image/gif");
readfile($from_name);
break;
case 2:
header("Content-type: image/jpeg");
readfile($from_name);
break;
case 3:
header("Content-type: image/png");
readfile($from_name);
break;
}
}
return;
}
if ($this->image_type == 1) {
// should use this function for gifs (gifs are palette images)
$ni = imagecreate($this->max_x, $this->max_y);
}
else {
// Create a new true color image
$ni = ImageCreateTrueColor($this->max_x,$this->max_y);
}
// Fill image with white background (255,255,255)
$white = imagecolorallocate($ni, 255, 255, 255);
imagefilledrectangle( $ni, 0, 0, $this->max_x, $this->max_y, $white);
// Create a new image from source file
$im = $this->ImageCreateFromType($orig_img_type,$from_name);
// Copy the palette from one image to another
imagepalettecopy($ni,$im);
// Copy and resize part of an image with resampling
imagecopyresampled(
$ni, $im, // destination, source
0, 0, 0, 0, // dstX, dstY, srcX, srcY
$this->max_x, $this->max_y, // dstW, dstH
$orig_x, $orig_y); // srcW, srcH
// save thumb file
$this->SaveImage($ni, $to_name);
if($temp) {
unlink($tmpfname); // this removes the file
}
}
}
?>
Second file named (thumb.php)
<?php
###############################################################
# Thumbnail Image Generator 1.3
###############################################################
# Visit http://www.zubrag.com/scripts/ for updates
###############################################################
// REQUIREMENTS:
// PHP 4.0.6 and GD 2.0.1 or later
// May not work with GIFs if GD2 library installed on your server
// does not support GIF functions in full
// Parameters:
// src - path to source image
// dest - path to thumb (where to save it)
// x - max width
// y - max height
// q - quality (applicable only to JPG, 1 to 100, 100 - best)
// t - thumb type. "-1" - same as source, 1 = GIF, 2 = JPG, 3 = PNG
// f - save to file (1) or output to browser (0).
// Sample usage:
// 1. save thumb on server
// http://www.zubrag.com/thumb.php?src=test.jpg&dest=thumb.jpg&x=100&y=50
// 2. output thumb to browser
// http://www.zubrag.com/thumb.php?src=test.jpg&x=50&y=50&f=0
// Below are default values (if parameter is not passed)
// save to file (true) or output to browser (false)
$save_to_file = true;
// Quality for JPEG and PNG.
// 0 (worst quality, smaller file) to 100 (best quality, bigger file)
// Note: PNG quality is only supported starting PHP 5.1.2
$image_quality = 100;
// resulting image type (1 = GIF, 2 = JPG, 3 = PNG)
// enter code of the image type if you want override it
// or set it to -1 to determine automatically
$image_type = -1;
// maximum thumb side size
$max_x = 100;
$max_y = 100;
// cut image before resizing. Set to 0 to skip this.
$cut_x = 0;
$cut_y = 0;
// Folder where source images are stored (thumbnails will be generated from these images).
// MUST end with slash.
$images_folder = '/www/images/';
// Folder to save thumbnails, full path from the root folder, MUST end with slash.
// Only needed if you save generated thumbnails on the server.
// Sample for windows: c:/wwwroot/thumbs/
// Sample for unix/linux: /home/site.com/htdocs/thumbs/
$thumbs_folder = '/www/thumbs/';
///////////////////////////////////////////////////
/////////////// DO NOT EDIT BELOW
///////////////////////////////////////////////////
$to_name = '';
if (isset($_REQUEST['f'])) {
$save_to_file = intval($_REQUEST['f']) == 1;
}
if (isset($_REQUEST['src'])) {
$from_name = urldecode($_REQUEST['src']);
}
else {
die("Source file name must be specified.");
}
if (isset($_REQUEST['dest'])) {
$to_name = urldecode($_REQUEST['dest']);
}
else if ($save_to_file) {
die("Thumbnail file name must be specified.");
}
if (isset($_REQUEST['q'])) {
$image_quality = intval($_REQUEST['q']);
}
if (isset($_REQUEST['t'])) {
$image_type = intval($_REQUEST['t']);
}
if (isset($_REQUEST['x'])) {
$max_x = intval($_REQUEST['x']);
}
if (isset($_REQUEST['y'])) {
$max_y = intval($_REQUEST['y']);
}
if (!file_exists($images_folder)) die('Images folder does not exist (update $images_folder in the script)');
if ($save_to_file && !file_exists($thumbs_folder)) die('Thumbnails folder does not exist (update $thumbs_folder in the script)');
// Allocate all necessary memory for the image.
// Special thanks to Alecos for providing the code.
ini_set('memory_limit', '-1');
// include image processing code
include('image.class.php');
$img = new Zubrag_image;
// initialize
$img->max_x = $max_x;
$img->max_y = $max_y;
$img->cut_x = $cut_x;
$img->cut_y = $cut_y;
$img->quality = $image_quality;
$img->save_to_file = $save_to_file;
$img->image_type = $image_type;
// generate thumbnail
$img->GenerateThumbFile($images_folder . $from_name, $thumbs_folder . $to_name);
?>
This is not nearly as easy as you may think.
To answer your question:
I want to build a website that offers online tools like "email extracting", "image resizing", etc, and I was wondering how to install tools with small PHP scripts like 1-2 .php files, and have them on different pages in the existing website
For each tool you want to integrate, you will want to create a separate plugin. This plugin can be as simple as a single PHP file but I'm guessing they are going to be more complex.
Some of the plugins you create will need admin pages unless you are planning on running them just on your own website. In these cases, it's safe to use a config file and just set the needed options there. it's not ideal, but it is quicker than creating an admin page.
Yes, some of your plugins will need database access. You wouldn't create a new database just for them though. Whenever possible, work within WordPress' existing DB structure. You have a lot of different tools at your disposal for saving off options both permanently and temporarily. As a last option, you could create your own table in the database just for your plugins but I would not do that unless there is absolutely no way to use the existing structures.
For integrating them into pages, the easy way is to use short codes. The modern way is to use Gutenberg blocks. Blocks take more time to code but if you are planning on selling/distributing these tools, people will expect them. If you are just using these on your own, a short-code would probably suffice.
Sorry I don't have a better answer for you but honestly, what you are asking is a lot of work. (and I've not even touched on auditing the code for security issues before integrating it into your site!)
Cheers! :)
=C=

Compress & resize images using PHP GD lib not working for png and weird results for jpg

I am trying to compress & resize my images using the php GD library. Nearly every answer on SO and everywhere else is the same, but for my solution, the PNG's are not being correctly transformed, and some jpg's are giving bizarre results.
This is the code I am using:
public function resizeImages() {
ini_set('max_execution_time', 0);
//Initial settings, Just specify Source and Destination Image folder.
$ImagesDirectory = FCPATH . 'design/img/test/'; //Source Image Directory End with Slash
$DestImagesDirectory = FCPATH . 'design/img/test/thumb/'; //Destination Image Directory End with Slash
$NewImageWidth = 150; //New Width of Image
$NewImageHeight = 150; // New Height of Image
$Quality = 90; //Image Quality
//Open Source Image directory, loop through each Image and resize it.
if($dir = opendir($ImagesDirectory)){
while(($file = readdir($dir))!== false){
$imagePath = $ImagesDirectory.$file;
$destPath = $DestImagesDirectory.$file;
$checkValidImage = #getimagesize($imagePath);
if(file_exists($imagePath) && $checkValidImage) //Continue only if 2 given parameters are true
{
//Image looks valid, resize.
if (resize_image($imagePath,$destPath,$NewImageWidth,$NewImageHeight,$Quality))
{
echo $file.' resize Success!<br />';
/*
Now Image is resized, may be save information in database?
*/
} else {
echo $file.' resize Failed!<br />';
}
}
}
closedir($dir);
}
}
and the resize_image function looks like this:
function resize_image($SrcImage,$DestImage, $MaxWidth,$MaxHeight,$Quality)
{
list($iWidth,$iHeight,$type) = getimagesize($SrcImage);
$ImageScale = min($MaxWidth/$iWidth, $MaxHeight/$iHeight);
$NewWidth = ceil($ImageScale*$iWidth);
$NewHeight = ceil($ImageScale*$iHeight);
$NewCanves = imagecreatetruecolor($NewWidth, $NewHeight);
$imagetype = strtolower(image_type_to_mime_type($type));
switch($imagetype)
{
case 'image/jpeg':
$NewImage = imagecreatefromjpeg($SrcImage);
break;
case 'image/png':
$NewImage = imagecreatefrompng($SrcImage);
break;
default:
return false;
}
//allow transparency for pngs
imagealphablending($NewCanves, false);
imagesavealpha($NewCanves, true);
// Resize Image
if(imagecopyresampled($NewCanves, $NewImage,0, 0, 0, 0, $NewWidth, $NewHeight, $iWidth, $iHeight))
{
switch ($imagetype) {
case 'image/jpeg':
if(imagejpeg($NewCanves,$DestImage,$Quality))
{
imagedestroy($NewCanves);
}
break;
case 'image/png':
if(imagepng($NewCanves,$DestImage,$Quality))
{
imagedestroy($NewCanves);
}
break;
default:
return false;
}
return true;
}
}
Every single png is not working, it just returns a file with 0 bytes and "file type is not supported", even though the type is recognized as .PNG in Windows...
Some JPG's return a weird result as well, see the following screenshot which indicates my issues regarding png's and some jpg's:
1) Do not use getimagesize to verify that the file is a valid image, to mention the manual:
Do not use getimagesize() to check that a given file is a valid image. Use a purpose-built solution such as the Fileinfo extension instead.
$checkValidImage = exif_imagetype($imagePath);
if(file_exists($imagePath) && ($checkValidImage == IMAGETYPE_JPEG || $checkValidImage == IMAGETYPE_PNG))
2) While imagejpeg() accepts quality from 0 to 100, imagepng() wants values between 0 and 9, you could do something like that:
if(imagepng($NewCanves,$DestImage,round(($Quality/100)*9)))
3) Using readdir () you should skip the current directory . and the parent..
while(($file = readdir($dir))!== false){
if ($file == "." || $file == "..")
continue;
edit
Point 2 is particularly important, imagepng () accepts values greater than 9 but then often fails with error in zlib or libpng generating corrupt png files.
I tried resizing some png and jpeg and I didn't encounter any problems with these changes.

imagick distort keep perspective

I have developed a function to distort a PNG-logotype with dragpoints (using this function: http://codepen.io/fta/pen/ifnqH). The logotype itself is an image inside the div with dragpoints.
This logotype can later be generated as an image using PHP + Image Magick using the Imagick module. The logotype could be round, narrow or any kind of shape but the image is always in a 1:1 ratio (ex: 800x800) filled with transparency.
Now to the problem:
I always wan't the logotype to have the ratio 1:1 regarding on how wide or narrow the dragged area is (i don't wan't the logotype itself to be stretched). Although, the image itself can be distorted.
The image on top illustrates how it works now, and the image in the bottom how i wan't it to work
http://i.stack.imgur.com/Ev0H8.jpg
Most importantly, this should work on the generated image using Image Magick + PHP. If it is possible to make it work on the client side using the dragpoints...that is a bonus.
I know how to get the real size of the logotype using $image->trimImage(0);
I should somehow be able to fill the edges of the image with extra transparency (x or y axis) to compensate for the stretch, but that is only so far i have come.
This is my PHP-function to stretch or scale the logotype
public function generate($file, $watermark, $offset = array()) {
$file = rtrim(DIR_IMAGE . str_replace(array('../', '..\\', '..'), '', $file));
$watermark = rtrim(DIR_IMAGE . str_replace(array('../', '..\\', '..'), '', $watermark));
$width = (int)$this->config->get('config_image_popup_width');
$height = (int)$this->config->get('config_image_popup_height');
if (is_file($file) && is_file($watermark)) {
$top = (int)$offset['top'];
$left = (int)$offset['left'];
$opacity = (float)$offset['opacity'];
$new_width = (int)$offset['width'];
$new_height = (int)$offset['height'];
$topleft_y = (float)$offset['transform_topleft_y'];
$topleft_x = (float)$offset['transform_topleft_x'];
$topright_y = (float)$offset['transform_topright_y'];
$topright_x = (float)$offset['transform_topright_x'];
$bottomleft_y = (float)$offset['transform_bottomleft_y'];
$bottomleft_x = (float)$offset['transform_bottomleft_x'];
$bottomright_y = (float)$offset['transform_bottomright_y'];
$bottomright_x = (float)$offset['transform_bottomright_x'];
$image = new ImageMagick($file);
$watermark = new ImageMagick($watermark);
// Resize the product image
$image->resize($width, $height);
// Perspective has not changed, scale only
if ($topleft_y == 0 && $topleft_x == 0 && $topright_y == 0 && $bottomleft_x == 0 && $topright_x == $bottomleft_y && $bottomleft_y == $bottomright_y && $bottomright_y == $bottomright_x) {
$watermark->scale($new_width, $new_height);
} else {
$watermark->perspective($offset);
}
$watermark->opacity($opacity);
$image->composite($watermark->get(), $left, $top);
return $image->base64output(100);
}

php imagecopyresized() making full black thumbnail

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

jQuery resize image before saving

I am new to jQuery but im loving it! ive have a problem i cant get round as of yet.
I am using http://www.zurb.com/playground/ajax_upload
which i have got working using the following upload.php
<?
$time= time();
$uploaddir = 'users/'; //<-- Changed this to my directory for storing images
$uploadfile = $uploaddir.$time.basename($_FILES['userfile']['name']); //<-- IMPORTANT
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo $uploaddir.$time.$_FILES['userfile']['name']; // IMPORTANT
#print_r($_FILES);
} else {
// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
// Otherwise onSubmit event will not be fired
echo "error";
}
?>
i have added the time variable to ensure each image is unique. The problem i have is i want to resize and optimise the image on the fly and i am not sure how to do this.
The resize is the most important featuer i require - for example i would like a max width of 300px for the image that is saved even if it was originally 1000px wide. I need to resize proportionaly ( is that a word? :) )
Any help will be great.
Regards
M
To resize images you need libs like GD
The standard function to do this is GD's imagecopyresampled.
In the example is shown one way to resize and keeping the proportion:
//> MAx
$width = 200;
$height = 200;
// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig) {
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}
There is two main image manipulation things in PHP, GD or Imagemagick. Both will be able to do what you need. You will need to configure them on your PHP webserver.

Categories