That's the code which generates the x-marks:
for ($i = 0; $i < $maxdata; $i++)
{
$xcoord = mt_rand(50, 450);
$ycoord = mt_rand(50, 450);
imagechar($im, 5, $xcoord, $ycoord, $string, $black);
if (($xcoord < 50) || ($xcoord > 450) || ($ycoord < 50) || ($ycoord > 450))
{
$p_bad += 1;
}
}
But this happens (got bad marks and at y-coord):
http://imgur.com/2TZXfY1
Rly don't know where is the problem, image size is 500 x 500 pixels, x-coord is from 50 to 450 pixel, and y-coord is from 50 to 450 pixel too ...
Related
I am trying to create an image with a pattern of a repeated circle. I am doing this in PHP with GD. So far I have been able to tile the circle in horizontal manner (x-axis) but am unable to tile it in the vertical(y-axis). Here is an example image.
Below is the code that created the above image :
$width = 1000;
$height = 500;
$image_p = imagecreatetruecolor($width, $height);
$color = imagecolorallocate($image_p, 0, 255, 0);
for ($i = 0; $i <= 10; $i++){
if ($i % 2 !== 0){ //only if odd numbers
imagefilledellipse ($image_p, 50 * $i, 50, 100, 100, $color);
}
}
imagejpeg($image_p, uniqid() .'.jpg');
My guess is that in order to tile each circle in a vertical manner it just needs another nested for loop and it would be similar to one already there except the change in y-axis like so :
imagefilledellipse ($image_p, 50, 50 * $i, 100, 100, $color);
I have tried a lot of nesting variation but could not get it to work. Please help.
The function imagefilledellipse has the following signature (I suppose):
imagefilledellipse(image, x, y, width, height, color)
Which means that you are drawing for every i in 0 < i < 10 a circle with a different x position.
Swap it with the y parameter to draw vertical circles:
$width = 1000;
$height = 500;
$image_p = imagecreatetruecolor($width, $height);
$color = imagecolorallocate($image_p, 0, 255, 0);
for ($i = 0; $i <= 10; $i++){
if ($i % 2 !== 0){ //only if odd numbers
imagefilledellipse ($image_p, 50, 50 * $i, 100, 100, $color);
}
}
imagejpeg($image_p, uniqid() .'.jpg');
In order to draw both horizontal and vertical circles you will need indeed, as you said, a nested for-loop:
$width = 1000;
$height = 500;
$image_p = imagecreatetruecolor($width, $height);
$color = imagecolorallocate($image_p, 0, 255, 0);
for ($i = 0; $i <= 10; $i++){
for ($j = 0; $j <= 10; $j++) {
if ($i % 2 !== 0 && $j % 2 !== 0) { //only if odd numbers
imagefilledellipse ($image_p, 50 * $i, 50 * $j, 100, 100, $color);
}
}
}
imagejpeg($image_p, uniqid() .'.jpg');
Also, you do not need to check for odd numbers if you would change the scale from i * 50 to 50 + i * 100, like this:
imagefilledellipse ($image_p, 50 + 100 * $i, 50 + 100 * $j, 100, 100, $color);
If you know how many columns you want it should be quite easy.
$colCounter=0;
$yAxis = 50;
for ($i = 0; $i <= 10; $i++){
if ($i % 2 !== 0){ //only if odd numbers
if ($colCounter % 5 === 0){ // Do something every 5 cols
$yAxis = $yAxis + 50 // add 50 onto each row
}
$colCounter++;//increment counter
imagefilledellipse ($image_p, 50 * $i, $yAxis, 100, 100, $color);
}
}
Note this is un-tested code
I am writing randomColorSelect() function, so that when the script is executed, prints the word RED 10% of the time, the word BLUE 50% of the time and the word GREEN 80% of the time: but not getting how to get this as i am new in PHP.
http://php.net/manual/en/function.rand.php
This should give the desired effect.
$red_dice = rand(0, 100); // 0% to 100%
$blue_dice = rand(0, 100); // 0% to 100%
$green_dice = rand(0, 100); // 0% to 100%
if ($red_dice <= 10)
{
echo "RED\n";
}
if ($blue_dice <= 50)
{
echo "BLUE\n";
}
if ($green_dice <= 80)
{
echo "GREEN\n";
}
Building on the believe that the percentages should add up to 100% total:
$number = rand(1, 100);
// 10%
if($number <= 10)
{
echo 'RED';
}
// 50%
else if(($number >= 11) && ($number <= 60))
{
echo 'BLUE';
}
// rest-%, in this case 30
else
{
echo 'GREEN';
}
What I'd like here is a working, optimized version of my current code. While my function does return an array with actual results, I don't know if they are correct (I'm not a mathematics guru and I don't know Java code to compare my results against known implementations). Secondly, I'd like the function to be able to accept custom table sizes, but I don't know how to do that. Is table size equivalent to resampling the image? Am I applying the coefficients correctly?
// a lot of processing is required for large images
$image = imagecreatetruecolor(21, 21);
$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
imagefilledellipse($image, 10, 10, 15, 15, $white);
print_r(imgDTC($image));
function imgDTC($img, $tableSize){
// m1 = Matrix1, an associative array with pixel data from the image
// m2 = Matrix2, an associative array with DCT Frequencies
// x1, y1 = coordinates in matrix1
// x2, y2 = coordinates in matrix2
$m1 = array();
$m2 = array();
// iw = image width
// ih = image height
$iw = imagesx($img);
$ih = imagesy($img);
// populate matrix1
for ($x1=0; $x1<$iw; $x1++) {
for ($y1=0; $y1<$ih; $y1++) {
$m1[$x1][$y1] = imagecolorat($img, $x1, $y1) & 0xff;
}
}
// populate matrix2
// for each coordinate in matrix2
for ($x2=0;$x2<$iw;$x2++) {
for ($y2=0;$y2<$ih;$y2++) {
// for each coordinate in matrix1
$sum = 1;
for ($x1=0;$x1<$iw;$x1++) {
for ($y1=0;$y1<$ih;$y1++) {
$sum +=
cos(((2*$x1+1)/(2*$iw))*$x2*pi()) *
cos(((2*$y1+1)/(2*$ih))*$y2*pi()) *
$m1[$x1][$y1]
;
}
}
// apply coefficients
$sum *= .25;
if ($x2 == 0 || $y2 == 0) {
$sum *= 1/sqrt(2);
}
$m2[$x2][$y2] = $sum;
}
}
return $m2;
}
My PHP function is a derivitive from this post in Java: Problems with DCT and IDCT algorithm in java. I have rewritten the code for php and readability. Ultimately, I am working on a script which will enable me to compare images and find similarities. The technique is outlined here: http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html.
Thanks!
This is how I performed my DCT what I'm doing here is to perform a 1 dimension DCT on each row. Then I took the result an perform the DTC on each column it's faster.
function dct1D($in) {
$results = array();
$N = count($in);
for ($k = 0; $k < $N; $k++) {
$sum = 0;
for ($n = 0; $n < $N; $n++) {
$sum += $in[$n] * cos($k * pi() * ($n + 0.5) / ($N));
}
$sum *= sqrt(2 / $N);
if ($k == 0) {
$sum *= 1 / sqrt(2);
}
$results[$k] = $sum;
}
return $results;
}
function optimizedImgDTC($img) {
$results = array();
$N1 = imagesx($img);
$N2 = imagesy($img);
$rows = array();
$row = array();
for ($j = 0; $j < $N2; $j++) {
for ($i = 0; $i < $N1; $i++)
$row[$i] = imagecolorat($img, $i, $j);
$rows[$j] = dct1D($row);
}
for ($i = 0; $i < $N1; $i++) {
for ($j = 0; $j < $N2; $j++)
$col[$j] = $rows[$j][$i];
$results[$i] = dct1D($col);
}
return $results;
}
Most algorithm I found on internet assume that the input matrix is 8x8. That's why you multiplyed by 0.25.
In general you should multiply by sqrt(2 / N) a 1D matrix and here we are in 2D so sqrt(2/N1) * sqrt(2/N2). If you do this for N1 = 8 and N2 = 8:
sqrt(2/8)^2 = 2/8 = 1/4 = 0.25
The other thing was to multiply by 1/sqrt(2) X0 it's for 1D matrix here we are in 2D so you multiply when k1 = 0 or k2 = 0. When k1 = 0 and k2 = 0 you have to do it twice.
First you need to test your function so find any working implementation. And compare results from your implementation with the results of the working implementation (with the same input).
If you whant your code to be faster you can look at this paper http://infoscience.epfl.ch/record/34246/files/Vetterli85.pdf (the first 2 parts).
In your case you can't use a custom table size because it should match the image size (can be wrong).
I'm downloading an image that already has black edges. Note: this isn't a result of me resizing an image. How can I use the GD library to detect and remove these black edges?
UPDATE
This is the cropped image using the script
I was able to come up with a time-consuming fix to this. Do the images being stored need to be stored with those black borders? It'd be much better if you could run every image with the black borders through the following script (using php to loop through every image in the directory) and let php override the old, black-bordered image with the new, borderless image.
The approach I took was to create 4 loops:
To look at black borders on the right (loop through x -> loop through y)
To look at black borders on the left (loop through x -> loop through y)
To look at black borders on the bottom (loop through y -> loop through x)
To look at black borders on the top (loop through y -> loop through x)
Now, each of these loops had another loop in them which would loop through the other coordinate (ie., x->y or y->x). If the inner loop found that one of the pixels lying on the outer loop's line wasn't black, it broke the whole look. If it didn't find that, it would increase one to the counter.
At the end, we simply create a new image with the new dimensions and copy from the new to the old one.
<?php
$image_path = "jcMHt.jpg";
$jpg = imagecreatefromjpeg($image_path);
$black = array("red" => 0, "green" => 0, "blue" => 0, "alpha" => 0);
$removeLeft = 0;
for($x = 0; $x < imagesx($jpg); $x++) {
for($y = 0; $y < imagesy($jpg); $y++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeLeft += 1;
}
$removeRight = 0;
for($x = imagesx($jpg)-1; $x > 0; $x--) {
for($y = 0; $y < imagesy($jpg); $y++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeRight += 1;
}
$removeTop = 0;
for($y = 0; $y < imagesy($jpg); $y++) {
for($x = 0; $x < imagesx($jpg); $x++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeTop += 1;
}
$removeBottom = 0;
for($y = imagesy($jpg)-1; $y > 0; $y--) {
for($x = 0; $x < imagesx($jpg); $x++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeBottom += 1;
}
$cropped = imagecreatetruecolor(imagesx($jpg) - ($removeLeft + $removeRight), imagesy($jpg) - ($removeTop + $removeBottom));
imagecopy($cropped, $jpg, 0, 0, $removeLeft, $removeTop, imagesx($cropped), imagesy($cropped));
header("Content-type: image/jpeg");
imagejpeg($cropped); //change to `imagejpeg($cropped, $image_path);` to save
imagedestroy($cropped);
imagedestroy($jpg);
<?php
$img = imagecreatefrompng("cuack.png");
$imagew = imagesx($img);
$imageh = imagesy($img);
$width = array();
$heigth = array();
$x = 0;
$y = 0;
for ($x = 0; $x <= $imagew; $x++) {
$rgba = imagecolorat($img,$x,1);
$alpha = ($rgba & 0x7F000000) >> 24;
var_dump($alpha);
}
for ($x = 0; $x <= $imageh; $x++) {
}
I'm trying to check every pixel in an image for transparent pixels, but I'm receiving the following error:
Notice: imagecolorat() [function.imagecolorat]: 1920,1 is out of bounds in C:\www\index.php on line 18
The boundaries start at 0 and thus extend to width − 1 and height − 1 in each direction. Therefore, the <= $imagew needs to be < $imagew. Likewise for <= $imageh.
Width and height just tell you how many rows and columns of pixels there are, not the maximum row or column index (which is one lower).
To walk the whole image, just use two nested loops:
for ($y = 0; $y < $imageh; $y++) {
for ($x = 0; $x < $imagew; $x++) {
// do whatever you want with them in here.
}
}