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)
Related
The function imagecopyresampled is useful to generate a thumbnail or resize images, while keeping aspect ratio:
$fn = $_FILES['data']['tmp_name'];
$size = getimagesize($fn);
$width = $size[0];
$height = $size[1];
$ratio = $width / $height;
if ($ratio > 1 && $size[0] > 500) { $width = 500; $height = 500 / $ratio; }
else { if ($ratio <= 1 && $size[1] > 500) { $width = 500 * $ratio; $height = 500; }}
$src = imagecreatefromstring(file_get_contents($fn));
$dst = imagecreatetruecolor($width, $height);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);
imagedestroy($src);
imagejpeg($dst, 'test.jpg');
imagedestroy($dst);
How can I select the resizing algorithm used by PHP?
Note: as stated in this question, setting imagesetinterpolation($dst, IMG_BILINEAR_FIXED); or such things doesn't seem to work.
According to tests I did (in another language), "bilinear resizing" sometimes gives better result than bicubic, and sometimes it's the contrary (depends if it's downsizing or upsizing).
(source: dpchallenge.com)
An alternative is the imagescale() function, that allows specifying the interpolation algorithm as a parameter:
imagescale($image, $new_width, $new_height, $algorithm);
According to the documentation $algorithm can be:
One of IMG_NEAREST_NEIGHBOUR, IMG_BILINEAR_FIXED, IMG_BICUBIC, IMG_BICUBIC_FIXED or anything else (will use two pass).
A test in PHP 7.0.15 (comparing file hash) shows that BICUBIC and BICUBIC_FIXED result in a different image, while BILINEAR_FIXED and NEAREST_NEIGHBOUR result in the same image.
imagecopyresampled is based/part of LibGD , by looking at the source code of LibGD, you can see clearly its implementation , also the documentation is not ambiguous about the used algorithm as it's stated that :
If the source and destination area differ in size, the area will be resized using bilinear interpolation for truecolor images, and nearest-neighbor interpolation for palette images.
So how can you select the resizing algorithm used by PHP?
If you insist/must use LibGD functions, you can't (unless you recompile PHP with a LibGD fork you code just for this matter).
However if you're free to use another image manipulation library, you can simply use one that use a different algorithm for resizing, for example Imagick seems to offer a wide range of interpolations but since the documentation is quite mute about it here is the constants needed to use the Imagick::setImageInterpolateMethod(int $) method :
const INTERPOLATE_UNDEFINED = 0;
const INTERPOLATE_AVERAGE = 1;
const INTERPOLATE_BICUBIC = 2;
const INTERPOLATE_BILINEAR = 3;
const INTERPOLATE_FILTER = 4;
const INTERPOLATE_INTEGER = 5;
const INTERPOLATE_MESH = 6;
const INTERPOLATE_NEARESTNEIGHBOR = 7;
const INTERPOLATE_SPLINE = 8;
Well you could download the PHP Source , add your filter function and compile php.
here you can find the filters https://github.com/php/php-src/blob/master/ext/gd/libgd/gd_interpolation.c#L481
here is the switch case where you have to apply the method https://github.com/php/php-src/blob/master/ext/gd/libgd/gd_interpolation.c#L2530
here you can define constants https://github.com/php/php-src/blob/master/ext/gd/libgd/gd.h#L137
happy hacking :D
Why do you not use a library? I think that if you use a php library it will be more easy. Try this one. Hope it will help you.
In a recent competition I was given the task to extract binary data (another PNG) from a PNG image file's alpha channel. The data was encoded in such a way that if I read the values in the alpha channel for each pixel from the top left (e.g. 80,78,71,13,10,26,10) up to a specific point then the resulting data would form another image.
Initially I tried to complete this task using PHP, but I hit a roadblock that I could not overcome. Consider the code below:
function pad($hex){
return strlen($hex) < 2 ? "0$hex" : $hex;
}
$channel = '';
$image = 'image.png';
$ir = imagecreatefrompng($image);
imagesavealpha($ir, true);
list($width, $height) = getimagesize($image);
for ($y = 0; $y < $height; $y++){
for ($x = 0; $x < $width; $x++){
$pixel = imagecolorat($ir, $x, $y);
$colors = imagecolorsforindex($ir, $pixel);
$a = pad(dechex($colors['alpha']));
$channel.= $a;
}
}
After running this, I noticed that the output did not contain the PNG magic number, and I just didn't know what went wrong. After a bit of digging I found out that $colors['alpha'] only contained values less than or equal to 127. Due to the data having been encoded with a 0-255 range in mind, I could not find a way to extract it, and ended up (successfully) solving the problem with node.js instead.
So, my question is: Is there any way I could have read the PNG file's alpha channel that would have returned the values in a 0 to 255 range as opposed to 0-127, or is this a hard-coded limitation of PHP and/or GD?
For the record, I tried to use ($colors['alpha']/127)*255 in order to try and forge the value in the incorrect range to the correct one, but to no avail.
It is a limitation of GD. According to https://bitbucket.org/libgd/gd-libgd/issues/132/history-behind-7-bit-alpha-component, in GD source it says:
gd has only 7 bits of alpha channel resolution, and 127 is
transparent, 0 opaque. A moment of convenience, a lifetime of
compatibility.
If you install ImageMagick PHP extension, you can get the alpha value between 0-255 for a pixel (let's say with x=300 and y=490) like this:
$image = new Imagick(__DIR__ . DIRECTORY_SEPARATOR . 'image.png');
$x = 300;
$y = 490;
$pixel = $image->getImagePixelColor($x, $y);
$colors = $pixel->getColor(true);
echo 'Alpha value: ' . round($colors['a'] * 255, 0);
ImageMagick: https://www.imagemagick.org
ImageMagick for PHP (called Imagick): http://php.net/manual/en/book.imagick.php
In your code:
list($width, $height) = getimagesize($image);
references a variable '$image' that was not defined in the code.
using getimagesize means $image is a filename.
so this line get's width and height from a filename.
This line broke the code when I tested it.
You already have your answer, but this is for posterity.
Considering the code, I feel:
$width=imagesx ($ir);
$height=imagesy ($ir);
Would be more logical (and actually works)
I've scoured around the internet a fair bit and I can't seem to find any reference to what I am attempting to achieve... I fear that means I'm probably going about doing something the wrong way, but I'll pose this question here anyways in hopes that maybe I am not.
I would like to take an already generated image that has a rectangular selection already drawn on it via a specific color and a dynamic (but always rectangular) path, and crop or cut-out (and use) the inner area of that rectangular path.
Let's use an image generated by google maps as an example for this:
I thought perhaps the imagemagick library would hold a solution for this, but, I don't know if it's because I haven't quite narrowed down the exact key terms for what I am looking to do exactly, or if it's because it cannot (at least not simply) be done, but I haven't turned up any solutions.
Any solutions, advice, or smacks to the head are welcome.
[Please note that (for now) I would like to operate under the assumption that these images already exist, so any information regarding the pixel coordinates of the relative selection area on the image doesn't exist]
Your problem seems to boil down to this: How do I find a red rectangle in an image?
This is quite an open-ended problem, and could actually be quite difficult to solve. However, if the following assumptions can be made, then the task will be a lot easier:
The rectangle is drawn in pure RGB red (#ff0000).
The rectangle is aligned parallel with the image edges.
The image is saved in a lossless format like PNG.
The image contains no other pixels of this exact colour.
We know the width of the rectangle's edges.
The example you provided seems to tick all these boxes. Since it's stored as an 8-bit indexed color image, the first step would be to convert it into a true color image. This makes it easier to check the pixel values.
Then find the outermost edges of the frame, inset the coordinates by the frame width, and crop the image. Here's some code that will do this for you:
<?php
$src_img = 'er7RT.png';
$frame_color = 0xff0000;
$frame_width = 6;
// Load image and copy to true color image resource
$im = imagecreatefrompng($src_img);
$sw = imagesx($im);
$sh = imagesy($im);
$im1 = imagecreatetruecolor($sw, $sh);
imagecopy ($im1, $im, 0, 0, 0, 0, $sw, $sh);
imagedestroy($im);
// Get outer dimensions of frame.
// Assume the frame color appears nowhere else in the image.
$minx = $miny = 999999;
$maxx = $maxy = -$minx;
for ($x=0; $x<$sw; $x++) for ($y=$sh/20; $y<$sh; $y+=$sh/10) {
if (imagecolorat($im1,$x,$y)==$frame_color) { $minx = $x; break 2; }
}
for ($x=$sw-1; $x>=0; $x--) for ($y=$sh/20; $y<$sh; $y+=$sh/10) {
if (imagecolorat($im1,$x,$y)==$frame_color) { $maxx = $x; break 2; }
}
for ($y=0; $y<$sh; $y++) for ($x=$sw/20; $x<$sw; $x+=$sw/10) {
if (imagecolorat($im1,$x,$y)==$frame_color) { $miny = $y; break 2; }
}
for ($y=$sh-1; $y>=0; $y--) for ($x=$sw/20; $x<$sw; $x+=$sw/10) {
if (imagecolorat($im1,$x,$y)==$frame_color) { $maxy = $y; break 2; }
}
if ($minx>=$maxx || $miny>=$maxy) die("Couldn't locate frame");
// Subtract frame width to obtain crop region
$minx += $frame_width;
$maxx -= $frame_width;
$miny += $frame_width;
$maxy -= $frame_width;
// Create new image with cropped dimensions
$im2 = imagecreatetruecolor($maxx-$minx, $maxy-$miny);
imagecopy ($im2, $im1, 0, 0, $minx, $miny, $maxx-$minx, $maxy-$miny);
// Finish up
header("Content-Type: image/png");
imagepng($im2);
imagedestroy($im1);
imagedestroy($im2);
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()
I have a jpeg image resource loaded into a variable in php. Given a grayscale value, like 6, how can I set a single, particular pixel to that grayscale value? My client has made it exceedingly clear that there is a big difference between grayscale and rgb.
Is this even doable in php with the GD library? If so, how?
Note: The script does indeed grayscale the entire image, but using an obscure algorithm. My script obtains the RGB for each pixel, and obtains the grayscale value corresponding to the algorithm. It just needs to now transform that pixel to that particular grayscale value.
You will probably find the the imagesetpixel function handy. The following is an example of how you could use it:
// $image = <GD image resource>
for($x = 0; $x < $width; x++)
{
for($y = 0; $y < $height; $y++)
{
$value = specialFunction($rgb_value);
// Depending on what the above function returns, the call below
// might have to be changed
$color = imagecolorallocate($image, $value, $value, $value);
imagesetpixel($image, $x, $y, $color);
}
}
Do you have access to the terminal or something along those lines to install Image Magick. If so, then you can could use the following
convert image.jpg -colorspace Gray image-bw.jpg
I'm not sure how to do it with the PHP GD Library sorry.