Solved

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

Posted on 2011-02-22
8
1,113 Views
Last Modified: 2012-06-27
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.

Can anyone help please!

Thanks in advance!






 200x200 with 100 diam circle
0
Comment
Question by:WarpFactor
8 Comments
 
LVL 7

Expert Comment

by:rcflyr
Comment Utility
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

by:Dushan911
Comment Utility
Sometimes you may achieve it using one of following functions.
http://www.php.net/manual/en/refs.utilspec.image.php
0
 
LVL 33

Expert Comment

by:Slick812
Comment Utility
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);


however I do not exactly understand your wanted readings of -
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

by:Lukasz Chmielewski
Comment Utility
Is the circle always in the center ?
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 

Author Comment

by:WarpFactor
Comment Utility
@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 33

Accepted Solution

by:
Slick812 earned 500 total points
Comment Utility
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);

?>

Open in new window

0
 

Author Closing Comment

by:WarpFactor
Comment Utility
A really terrific prototype and starting place that helps me get on my way!
0
 

Author Comment

by:WarpFactor
Comment Utility
@Slick812: Thanks so much. Works like a charm and is a great starting place.

@Everyone else: thanks so much for posting!
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
These days socially coordinated efforts have turned into a critical requirement for enterprises.
This tutorial demonstrates how to identify and create boundary or building outlines in Google Maps. In this example, I outline the boundaries of an enclosed skatepark within a community park.  Login to your Google Account, then  Google for "Google M…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now