php - Best way to blur images - php

I'm trying to blur first image like third one,But I cant do it ! :(
header('Content-Type: image/jpeg');
$image = imagecreatefromjpeg('1.jpg');
for ($x=1; $x<=40; $x++){
imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR,999);
}
imagefilter($image, IMG_FILTER_SMOOTH,99);
imagefilter($image, IMG_FILTER_BRIGHTNESS, 10);
imagejpeg($image);
imagedestroy($image);

Try to scale down the image and apply the loop with gaussian blur on the resized image. That way you will save some performance on large images:
header('Content-Type: image/jpeg');
$file = '1.jpg';
$image = imagecreatefromjpeg($file);
/* Get original image size */
list($w, $h) = getimagesize($file);
/* Create array with width and height of down sized images */
$size = array('sm'=>array('w'=>intval($w/4), 'h'=>intval($h/4)),
'md'=>array('w'=>intval($w/2), 'h'=>intval($h/2))
);
/* Scale by 25% and apply Gaussian blur */
$sm = imagecreatetruecolor($size['sm']['w'],$size['sm']['h']);
imagecopyresampled($sm, $image, 0, 0, 0, 0, $size['sm']['w'], $size['sm']['h'], $w, $h);
for ($x=1; $x <=40; $x++){
imagefilter($sm, IMG_FILTER_GAUSSIAN_BLUR, 999);
}
imagefilter($sm, IMG_FILTER_SMOOTH,99);
imagefilter($sm, IMG_FILTER_BRIGHTNESS, 10);
/* Scale result by 200% and blur again */
$md = imagecreatetruecolor($size['md']['w'], $size['md']['h']);
imagecopyresampled($md, $sm, 0, 0, 0, 0, $size['md']['w'], $size['md']['h'], $size['sm']['w'], $size['sm']['h']);
imagedestroy($sm);
for ($x=1; $x <=25; $x++){
imagefilter($md, IMG_FILTER_GAUSSIAN_BLUR, 999);
}
imagefilter($md, IMG_FILTER_SMOOTH,99);
imagefilter($md, IMG_FILTER_BRIGHTNESS, 10);
/* Scale result back to original size */
imagecopyresampled($image, $md, 0, 0, 0, 0, $w, $h, $size['md']['w'], $size['md']['h']);
imagedestroy($md);
// Apply filters of upsized image if you wish, but probably not needed
//imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
//imagefilter($image, IMG_FILTER_SMOOTH,99);
//imagefilter($image, IMG_FILTER_BRIGHTNESS, 10);
imagejpeg($image);
imagedestroy($image);
I have borrowed the downsizing idea and some of the code form this answer
I have tested the solution with your image, and the result:
You can elaborate and increase/decrease the blur by changing the number of loops for the small image. If you change for ($x=1; $x <=40; $x++){ to for ($x=1; $x <=75; $x++){ you will get more blur.
The downside to this solution is that you will get som visible pixelation because of the resizing going on. The upside is better performance, less server load and execution time compared to if you would apply the blur loop on the original sized image.

i also faced this problem in my project that time i use some long code but i think that, that code is not proper and create my own small code, here is that code
header("content-type: image/png");
$image = imagecreatefromjpeg("abc.jpg");
for ($x=1; $x<=50; $x++)
{
imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
}
imagepng($image);
imagedestroy($image);

A note on the IMG_FILTER_SMOOTH steps in Michael K's answer:
imagefilter($sm, IMG_FILTER_SMOOTH,99);
According to PHP:imagefilter
IMG_FILTER_SMOOTH
Applies a 9-cell convolution matrix where center pixel has the weight arg1 and others weight of 1.0. The result is normalized by dividing the sum with arg1 + 8.0 (sum of the matrix).
any float is accepted, large value (in practice: 2048 or more) = no change
So the arg1 in imagefilter() weighs the center pixel of the 3x3-kernel in relation to the other pixels. A value of 99 will not change anything and can be skipped. For more blur, you want to use a small arg1 (below 8).

I had similar issue coding with Laravel, I used following solution:
$image = \Image::make($path);
$width = $image->getWidth();
$height = $image->getHeight();
$image->resize(round($width / 5), round($height / 5));
$image->blur(10);
$image->resize($width, $height);
$image->blur(70);
$image->save($path, 60, 'jpg');
Laravel uses http://image.intervention.io/, it can be used standalone.
You can change how much times to resize the image, how much blur to apply on small and enlarged image afterwards.

easy
header('Content-Type: image/jpeg');
$image = imagecreatefromjpeg('1.jpg');
$image = imagescale($image , $YOU_IMG_WIDTH/40, $YOU_IMG_WIDTH/40);
imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
$image = imagescale($image , $YOU_IMG_WIDTH, $YOU_IMG_HEIGHT);
imagejpeg($image);
imagedestroy($image);

Related

Drawing a curved line between two points in PHP

I want to draw a simple curved line between two points. More specifically, the top left and bottom right corner of an image of arbitrary size.
I tried using imagearc, but apparently that's not what I'm looking for.
To illustrate what I mean:
I can't find any function to help me along, so any help would be appreciated :)
You could use ImageMagick instead of image gd. Image gd has no build-in support for curves.
If you don't have the possibility to use ImageMagick, you could still use imagesetpixel and create your own curve with a simple de casteljau algorithm
I solved it using imagearc after all.
The trick is to set the bottom left corner as the center, -90° start angle, 0° end angle and double the size of the image:
//GET VARS
$width = $_GET['width'];
$height = $_GET['height'];
//CREATE IMGS
$image = imagecreatetruecolor($width, $height);
$color = imagecolorallocate($image, 255, 0, 0);
imagearc( $image,
0, 0, //center point = bottom-left corner
$width*2, $height*2, //size = image size * 2
-90, //top left
0, //bottom right
$color);
//OUTPUT IMAGE
header('Content-Type: image/png');
imagepng($image);
//DESTROY IMAGE
imagedestroy($image);
Looks like this:
http://www.schizosplayground.com/pers/curvedlinetest.php?width=132&height=163
I solved a similar problem by generating a vector with points ($polygon) via any convinient function and then drew a lines inbetween the points:
$numberofpoints=count($polygon)/2-1; // XY coordinates, so points is just half and subtracting the end point
for ($i=0; $i < $numberofpoints;$i++) {
imageline($image, $polygon[2*$i], $polygon[2*$i+1], $polygon[2*$i+2], $polygon[2*$i+3], $Color); // connect two consecutive points with a line
}

How to generate a completely random image?

I'm trying to generate a completely random image of a given size.
Here is what I have so far:
<?php
$Width = 64;
$Height = 32;
$Image = imagecreate($Width, $Height);
for($Row = 1; $Row <= $Height; $Row++) {
for($Column = 1; $Column <= $Width; $Column++) {
$Red = mt_rand(0,255);
$Green = mt_rand(0,255);
$Blue = mt_rand(0,255);
$Colour = imagecolorallocate ($Image, $Red , $Green, $Blue);
imagesetpixel($Image,$Column - 1 , $Row - 1, $Colour);
}
}
header('Content-type: image/png');
imagepng($Image);
?>
The problem is that after 4 rows it stops being random and fills with a solid colour like this
if you change imagecreate to imagecreatetruecolor it should work (everything else is the same, including the parameters)
By allocating a new color for each pixel, you are quickly exhausting the color palate. 4 rows at 64 pixels per row is 256. After the palate is full, any new color will use the last color on the palate.
Mishu's answer uses a full-color image, rather than and indexed color image, which is why you are able to allocate more colors.
See this answer in the PHP docs http://us.php.net/manual/en/function.imagecolorallocate.php#94785
Both create images with different palletes. True color has more color ranges so its better to use imagecreatetruecolor()

PHP GD poor thumb quality

$tmp_im = imagecreatetruecolor($width, $height);
$x = $this->getX();
$y = $this->getY();
$w = floor($resize_height * ($x / $y));
$h = $resize_height;
$this->tmp_im = imagecreatetruecolor($w, $h);
imagealphablending($this->tmp_im, false);
imagesavealpha($this->tmp_im, true);
imagecopyresampled($this->tmp_im, $this->im, 0, 0, 0, 0, $w, $h, $this->getX(), $this->getY());
$this->im = $this->tmp_im;
$hs = floor(($width - $this->getX())/2);
$vs = floor(($height - $this->getY())/2);
imagecopy($tmp_im, $this->im, $hs, $vs, 0, 0, $this->getX(), $this->getY());
$this->im = $tmp_im;
the results is a poor quality resized image, what im doing wrong? i also tried to use a imagejpeg with quality = 100
Use imagecopytruecolor() instead of
imagecopy($tmp_im, $this->im, $hs, $vs, 0, 0, $this->getX(), $this->getY());
This is a Notice on the official PHP documentation page:
There is a problem due to palette image limitations (255+1 colors).
Resampling or filtering an image commonly needs more colors than 255,
a kind of approximation is used to calculate the new resampled pixel
and its color. With a palette image we try to allocate a new color, if
that failed, we choose the closest (in theory) computed color. This is
not always the closest visual color. That may produce a weird result,
like blank (or visually blank) images. To skip this problem, please
use a truecolor image as a destination image, such as one created by
imagecreatetruecolor().

imagettfbbox & imagettftext - resize,position,rotate

Ok, now it's officialy 10 hours that I'm trying to make this work, but by every minute I'm farther and farther from the final goal...
The thing is, I need to create a function, class or whatever that by the selected TTF or truetype font create, properly resize, and fill the image with a text given by the url. The image shouldn't be longer than that text.
I've given up on all my codes, and the best thing I've got so far is taken from the net ...
<?php
if(!isset($_GET['size'])) $_GET['size'] = 20;
if(!isset($_GET['text'])) $_GET['text'] = "Moj tekst";
$get_font = ( isset( $_GET['font'] ) ) ? $_GET['font'] : 'arial';
$size = imagettfbbox($_GET['size'], 0, "font/".$get_font.".ttf", $_GET['text']);
$xsize = abs($size[0]) + abs($size[2]);
$ysize = abs($size[5]) + abs($size[1]);
$image = imagecreate($xsize, $ysize);
imageSaveAlpha($image, true);
ImageAlphaBlending($image, false);
$transparentColor = imagecolorallocatealpha($image, 200, 200, 200, 127);
Imagefill($image, 0, 0, $transparentColor);
$blue = imagecolorallocate($image, 0, 0, 255);
$white = ImageColorAllocate($image, 255,255,255);
$black = ImageColorAllocate($image, 0,0,0); //-($_GET['size']/20)
imagettftext($image, $_GET['size'], 0, abs($size[0]), abs($size[5]), $black, "font/".$get_font.".ttf", $_GET['text']);
header("content-type: image/png");
imagepng($image);
imagedestroy($image);
?>
This code is ok, although the edge of the last or first latter is sometimes partly hidden or just it doesn't fit into the created image (depending on font size), which isn't the problem with smaller font size. And the function i really need is by changing image's rotation to change the entire images proportions so the text fits in.
Example : http://img199.imageshack.us/img199/9368/32739521.jpg
Also, if there is finished function or class that does this, it would be great.. :'( :)
If you are always missing one letter of the end of the beginning, why not just add the width of a single letter to your final size?
In my experience, imagettfbbox doesn't do a very good job of deciding what does and doesn't fit within a bounding box - you need to fudge it a little yourself :)
Hope this helps.
Luke Peterson

PHP/GD Gaussian Blur Effect

I need to obfuscate a certain area of an image using PHP and GD, currently I'm using the following code:
for ($x = $_GET['x1']; $x < $_GET['x2']; $x += $pixel)
{
for ($y = $_GET['y1']; $y < $_GET['y2']; $y += $pixel)
{
ImageFilledRectangle($image, $x, $y, $x + $pixel - 1, $y + $pixel - 1, ImageColorAt($image, $x, $y));
}
}
This basically replaces the selected area with squares of $pixel pixels. I want to accomplish some kind of blur (gaussian preferably) effect, I know I can use the ImageFilter() function:
ImageFilter($image, IMG_FILTER_GAUSSIAN_BLUR);
But it blurs the entire canvas, my problem is that I just want to blur a specific area.
You can copy a specific part of the image into a new image, apply the blur on the new image and copy the result back.
Sort of like this:
$image2 = imagecreate($width, $height);
imagecopy ( $image2 , $image , 0 , 0 , $x , $y , $width , $height);
imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
imagecopy ($image, $image2, $x, $y, 0, 0, $width, $height);
I did not check the documentation for imagefilter and I don't know if this is impossible or if there is an equivalent to applying this to (a part) of an image. But assuming there isn't, why not:
Copy the part you want to blur to a new (temporary) GD image (no need to write it to disk, just assign it to a new temp variable).
Apply gaussian blur filter to this temporary image.
Copy the resulting (filtered) image right back where it came from (functionality to do this is definitely in the GD library)

Categories