How to generate a completely random image? - php

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()

Related

php - Best way to blur images

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

Drawing rectangles in php not working

I am creating an image in php and populating it with 10x10 pixel rectangles filled with a color.
$image = imagecreate(150,150);
$background = imagecolorallocate($image, 0, 0, 0); //black background
for ($row=0; $row < 15; $row++) {
for ($col=0; $col < 15; $col++) {
$x1 = 10* $col;
$y1 = 10*$row;
$x2 = 10*($col + 1);
$y2 = 10*($row + 1);
imagefilledrectangle($image, $x1,$y1,$x2,$y2, imagecolorallocate($image, 100,100,100)); //grey rectangle
}
}
imagepng($image, "ciph.png");
This works for small images no bigger than 150x150 pixels and i get a completely grey filled rectangle. but soon as i try bigger images. it only adds rectangles to part of the image. Any idea what is causing this? it appears there is a limit on the number of individual objects i can draw.
15x15
18x18
ive counted and it appears to only draw 256 rectangles... doesnt seem like a coincidence that that is 2 to the 8th power.
Any help would be much appreciated! thanks.
The problem lies in how you're creating the image. If you change first line from:
$image = imagecreate(150,150);
to:
$image = imagecreatetruecolor(150,150);
it will allow more than 256 rectangles to be drawn to the image.
imagecreatetruecolor() also gives the image a black background by default, instead of the blank background that imagecreate() gives, so you won't need the second line as well.

Name of image and way to generate it

I frequently see the following kind of images on many websites (on StackOverflow for example).
What is this kind of image called and how do I generate it? (preferably in PHP)
Duplicate question, but here is more to read about: http://en.wikipedia.org/wiki/Identicon
Using GD library and this source http://sourceforge.net/projects/identicons/ for PHP
Quote from wiki, for those who are lazy to open the link:
An Identicon is a visual representation of a hash value, usually of an IP address, that serves to identify a user of a computer system as a form of avatar while protecting the users' privacy. The original Identicon was a 9-block graphic, and the representation has been extended to other graphic forms by third parties.
You can a try this code something similar to your above query.
[Not a direct answer though]
<?php
$Width = 64;
$Height = 64;
$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);
}
}
header('Content-type: image/png');
imagepng($Image);
?>
Generates a random color each and every time like this.
Just google 'gravatar'.... (as an alternative to what u wanted)

Create a picture with GD containing other images

I would like to create a picture in PHP with GD composed by different other pictures. For example I have 6 pictures (or more) and I would like to create ONE picture who contain these different pictures.
The Difficulty is that my final picture must have a fixed width and height (304x179), so if the different pictures are too big they must be cut. This is an example from IconFinder :
This picture is composed by 6 images, but the 3rd bird (green) is cutted, and the 4, 5 and 6 are cutted in the bottom. This is what I want, can you give me some help to write this code in PHP ?
Thanks
Create your primary image and consider it your "canvas."
From there, use imagecopy() to copy the smaller images into the canvas image.
See this for example:
<?php
header('Content-Type: image/jpg');
$canvas = imagecreatetruecolor(304, 179);
$icon1 = imagecreatefromjpeg('icon.jpg');
$icon2 = imagecreatefromjpeg('icon2.jpg');
// ... add more source images as needed
imagecopy($canvas, $icon1, 275, 102, 0, 0, 100, 100);
imagecopy($canvas, $icon2, 0, 120, 0, 0, 100, 100);
// ... copy additional source images to the canvas as needed
imagejpeg($canvas);
?>
In my example, icon.jpg is a 100x100 image which I am placing in the canvas such that its top left corner is located at 275, 102 in the canvas, which cuts off the right side.
Edit
I adjusted the code to be more similar to what you're doing.
Here a none tested modify spinet from one of my scripts, hope it can be usefull:
header('Content-type: image/png');
$image = array() //Populate this array with the image paths
//Create the Letters Image Objects
foreach($image as $a){
$image['obj'][] = imageCreateFromPNG($a);
}unset($a);
$canvasW = 300;
$canvasH = 300;
//Create Canvas
$photoImage = imagecreatetruecolor($canvasW,$canvasH);
imagesavealpha($photoImage, true);
$trans_color = imagecolorallocatealpha($photoImage, 0, 0, 0, 127);
imagefill($photoImage, 0, 0, $trans_color);
//Merge Images
$Offset_y = 0;
$images_by_row = 3;
$images_rows_height = 100; // height of each image row
$counter = 0;
foreach($image['obj'] as $a){
$counter++;
$width = ceil(imagesx($a));
$height = ceil(imagesy($a));
if(!isset($offset)){ $offset = 1; }
imageComposeAlpha($photoImage, $a, $offset, $Offset_y,$width,$height);
if($offset >= 1){
$offset = $offset + $width;
}
//Check if new row next time
if($counter >= $images_by_row){
if($images_by_row%$counter){
$offset_y += $images_rows_height;
}
}
}unset($a);
imagepng($photoImage);

Generate colour palette from an image

Just for fun I've been looking at how to use the GD library to create a colour palette from an image. So far I've used GD to resize a user uploaded image to an appropriate size for displaying on a webpage.
Now I'd like to be able to get about five or so different colours from the image that represent the range of colours present in it. Once I've done that I'd like to generate a complementary palette based upon those colours, which I can then use to colour different elements on the page.
Any help I can get about how I would find the initial colour palette would be much appreciated!
EDIT:
I've come to my own solution which you can see below.
Well I've spent a couple of days fiddling around and this is how I managed to build my colour palette. Its worked fairly well for me and you can change the size of the colour palette to return more or less colours from the image.
// The function takes in an image resource (the result from one
// of the GD imagecreate... functions) as well as a width and
// height for the size of colour palette you wish to create.
// This defaults to a 3x3, 9 block palette.
function build_palette($img_resource, $palette_w = 3, $palette_h = 3) {
$width = imagesx($img_resource);
$height = imagesy($img_resource);
// Calculate the width and height of each palette block
// based upon the size of the input image and the number
// of blocks.
$block_w = round($width / $palette_w);
$block_h = round($height / $palette_h);
for($y = 0; $y < $palette_h; $y++) {
for($x = 0; $x < $palette_w; $x++) {
// Calculate where to take an image sample from the soruce image.
$block_start_x = ($x * $block_w);
$block_start_y = ($y * $block_h);
// Create a blank 1x1 image into which we will copy
// the image sample.
$block = imagecreatetruecolor(1, 1);
imagecopyresampled($block, $img_resource, 0, 0, $block_start_x, $block_start_y, 1, 1, $block_w, $block_h);
// Convert the block to a palette image of just one colour.
imagetruecolortopalette($block, true, 1);
// Find the RGB value of the block's colour and save it
// to an array.
$colour_index = imagecolorat($block, 0, 0);
$rgb = imagecolorsforindex($block, $colour_index);
$colour_array[$x][$y]['r'] = $rgb['red'];
$colour_array[$x][$y]['g'] = $rgb['green'];
$colour_array[$x][$y]['b'] = $rgb['blue'];
imagedestroy($block);
}
}
imagedestroy($img_resource);
return $colour_array;
}
this may help you
<?php
$im = ImageCreateFromJpeg($source_file);
$imgw = imagesx($im);
$imgh = imagesy($im);
// n = total number or pixels
$n = $imgw*$imgh;
$colors = array();
for ($i=0; $i<$imgw; $i++)
{
for ($j=0; $j<$imgh; $j++)
{
$rgb = ImageColorAt($im, $i, $j);
if (isset($colors[$rgb])) {
$colors[$rgb]++;
}
else {
$colors[$rgb] = 1;
}
}
}
asort($colors);
print_r($colors);
The imagecolorat function will give you the colour value at a pixel which you can use to scan the image and create a colour histogram:
http://www.php.net/manual/en/function.imagecolorat.php

Categories