Go Premium for a chance to win a PS4. Enter to Win

x
Solved

# PHP GD - Finding coordinates of specific pixels in a PNG file

Posted on 2011-02-22
Medium Priority
1,346 Views
Hi there,

As an example, imagine a 200x200 pixel wide PNG file. The entire file is transparent except for a circle in the dead center that has a diameter of 100 pixels. The circle is black and the edges are aliased, but I don't want to use the circle's color at all in this question because I may have 1000 images with the circle being different or multi-colored.

What I need to do is this:

Open the PNG and find the x/y coordinate of the first pixel that is NOT transparent on the left, top, right and bottom of the circle. All I care about is those four points. Note that the size of circle may change so I need to do this dynamically.

If I were using exactly what I said the script should come back with:
50,100 (left)
100,50 (top)
150, 100 (right)
100,150 (bottom)

I've gone through the GD functions and can't seem to find the right tool or the right combinations.

0
Question by:WarpFactor

LVL 7

Expert Comment

ID: 34956345
The GD tools don't seem to have an option to check the transparency of a specific pixel.

If you know the circle is going to be in the middle of the image then you can assume the color of the first pixel is not going to be the color of the circle.  Store that color, then loop through each pixel of the image (using imagesx and imagesy for width and height) and compare each pixel to the first to see if it is different (using imagecolorat).

When you find a color that doesn't match, check if it is the lowest or highest x or y value you have seen. If so, update your high/low x/y counters and continue.

When you are finished looping through the image you will have your maximum and minimum x and y values that you can use to calculate the edges of the circle.
0

LVL 17

Expert Comment

ID: 34956626
Sometimes you may achieve it using one of following functions.
http://www.php.net/manual/en/refs.utilspec.image.php
0

LVL 34

Expert Comment

ID: 34957208
greetings WarpFactor,, you might could use something like the code below to get an Alpha transparency setting for all of the pixels in an image. - -

\$img = imagecreatefrompng('images/circle.png');
\$wid = imagesx(\$img);
\$hgt = imagesy(\$img);

for(\$y = 0; \$y < \$hgt; ++\$y){
for(\$x = 0; \$x < \$wid; ++\$x){
\$color = imagecolorat(\$img, \$x, \$y);
\$alpha = (\$color >> 24) & 255;
if (\$alpha > 70) \$transparent = true;
}
}
imagedestroy(\$img);

50,100 (left)
100,50 (top)
150, 100 (right)
100,150 (bottom)

I do not believe that the image circle you show above would have those exact placement pixels, are you willing to have a tolerance due to the variable transparency of edge pixels? ?
0

LVL 27

Expert Comment

ID: 34958504
Is the circle always in the center ?
0

Author Comment

ID: 34962532
@Slick812: I will try your code and a very big thanks for that. Answering your question: yes, there could be a tolerance of a couple pixels here and there. Said another way, I am looking for the first pixel from the top center of the image that is not transparent (being the top of the circle). This is the same for the left center, etc.

@rcflyr: thanks and a really good idea, but the circle is just the example of what I need to do. The images would be more complicated in production.

@Roads_Roads: more than likely, but as above, the images will be more complicated.

What I was hoiping to do is parse each row or column of pixels from whatever starting point I chose. Because I know I'm going to be dealing with transparence (an alpha setting), all I care about is finding things that are not this setting, and then figuring out the edges from there.

0

LVL 34

Accepted Solution

Slick812 earned 2000 total points
ID: 34962817
I considered some different ways to do this, and This could get very complicated in a big hurry if what you say - "The images would be more complicated in production" is true. I tried to think about your future requirement of -
"I'm going to be dealing with transparency (an alpha setting), all I care about is finding things that are not this setting, and then figuring out the edges from there." along with "the images will be more complicated"
You could do an Entire Image Pixel analyst , getting the alpha for every pixel, However, if you are NOT confined to simple image shapes, then the artificial intelligence to will need to figure out, using if - then  or switch statements will take much time, I would guess.

I did this code below, using the png image you supplied  squarecircle.png, , to keep it somewhat simple, I have it using ONLY centered circles or rectangles, to give credible results.

I have done stuff with images before, so I have an "Image Test" first which will make sure the image pixels at the four corners are transparent, and the center pixel is NOT transparent, but these tests can be changed, but if your images are NOT from a reliable source , you must test them for some minimum spects (larger than 1x1 pixels or less than 2000x2000 pixels, for example), or your code may spin out on you.

see if you can figure what I have done in this code, and if it is something you might start with.
``````<?php

\$img = imagecreatefrompng('images3/squarecircle.png');
\$width = imagesx(\$img);
\$height = imagesy(\$img);
\$hgtHalf = (int)(\$height / 2);
\$widHalf = (int)(\$width / 2);

\$aryTest = array();
\$aryTest[] = imagecolorat(\$img, 0, 0) >> 24;

\$aryTest[] = imagecolorat(\$img, \$width-1, 0) >> 24;

\$aryTest[] = imagecolorat(\$img, 0, \$height-1) >> 24;

\$aryTest[] = imagecolorat(\$img, \$width-1, \$height-1) >> 24;

\$aryTest[] = imagecolorat(\$img, \$widHalf, \$hgtHalf);

\$doImage = true;
if (\$aryTest[4] != 0) \$doImage = false;
else
for (\$x = 0; \$x < 4; ++\$x)
if (\$aryTest[\$x] != 127) {
\$doImage = false;
break;
}

if (\$doImage) {
\$aryTest = array(-1,-1,-1,-1);
for (\$x = 0; \$x < \$widHalf; ++\$x) {
\$color = imagecolorat(\$img, \$x, \$hgtHalf) >> 24;
if (\$color < 64) {
\$aryTest[0] = \$x;
break;
}
}

for (\$x = \$width-1; \$x > \$widHalf; --\$x) {
\$color = imagecolorat(\$img, \$x, \$hgtHalf) >> 24;
if (\$color < 64) {
\$aryTest[1] = \$x;
break;
}
}

for (\$y = 0; \$y < \$hgtHalf; ++\$y) {
\$color = imagecolorat(\$img, \$widHalf, \$y) >> 24;
if (\$color < 64) {
\$aryTest[2] = \$y;
break;
}
}

for (\$y = \$height-1; \$y > \$hgtHalf; --\$y) {
\$color = imagecolorat(\$img, \$widHalf, \$y) >> 24;
if (\$color < 64) {
\$aryTest[3] = \$y;
break;
}
}

for (\$x = 0; \$x < 4; ++\$x)
if (\$aryTest[\$x] == -1) {
echo 'ERROR = Image find circle FAILED to get soild color on '.\$x.' pass.<br />';
//break;
}

echo 'Minimum X value is '.\$aryTest[0].', Maximum X value is '.\$aryTest[1].', Minimum Y value is '.
\$aryTest[2].', Maximum Y value is '.\$aryTest[3].'<br />';
} else
echo 'ERROR = Image Corners are NOT Transparent, can not find circle.';

imagedestroy(\$img);

?>
``````
0

Author Closing Comment

ID: 34981457
A really terrific prototype and starting place that helps me get on my way!
0

Author Comment

ID: 34981469
@Slick812: Thanks so much. Works like a charm and is a great starting place.

@Everyone else: thanks so much for posting!
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Originally, this post was published on Monitis Blog, you can check it here . It goes without saying that technology has transformed society and the very nature of how we live, work, and communicate in ways that wouldâ€™ve been incomprehensible 5 yeâ€¦
Without even knowing it, most of us are using web applications on a daily basis. Â In fact, Gmail and Yahoo email, Twitter, Facebook, and eBay are used by most of us dailyâ€”and they are web applications. We generally confuse these web applications toâ€¦
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: Tâ€¦
The viewer will learn how to dynamically set the form action using jQuery.
###### Suggested Courses
Course of the Month12 days, 9 hours left to enroll