NaturalBornCamper - 5 months ago 16x
PHP Question

# Find the 4 coordinates of a rotated transparent rectangle in png image

I didn't find anything about the subject, but I am dreaming vividly or is it possible in PHP to scan a PNG image and find the transparent positions in a picture?

for example, if there is a image of a TV with a transparent hole where the screen is. Can I find the most top-left, most top-right, most bottom-left, most bottom-right coordinates of transparent pixels by scanning the alpha-channel?

Not sure if there's a library doing this, I checked real quick but did not find..

Maybe not the most elegant solution and I'm sure there's a better way of doing it, but this works for a well-formed png image

``````// Returns the coordinates of a transparent rectangle in a PNG file (top left, top right, lower left, lower right
public function getTransparentRectangleCoordinates(\$fileUrl)
{
define ('TRANSPARENCY_THRESHOLD', 100); // 127=fully transparent, 0=black

\$img = @imagecreatefrompng(\$fileUrl);

if (!\$img) return ('Invalid PNG Image');

\$coordLowestX = array(imagesx(\$img), '');
\$coordHighestX = array(0, '');
\$coordLowestY = array('', imagesy(\$img));
\$coordHighestY = array('', 0);

\$minX = imagesx(\$img);
\$maxX = 0;
\$minY = imagesy(\$img);
\$maxY = 0;

// Scanning image pixels to find transparent points
for (\$x=0; \$x < imagesx(\$img); ++\$x)
{
for (\$y=0; \$y < imagesy(\$img); ++\$y)
{
\$alpha = (imagecolorat(\$img, \$x, \$y) >> 24) & 0xFF;
if (\$alpha >= TRANSPARENCY_THRESHOLD)
{
if (\$x < \$coordLowestX[0]) \$coordLowestX = array(\$x, \$y);
if (\$x > \$coordHighestX[0]) \$coordHighestX = array(\$x, \$y);
if (\$y < \$coordLowestY[1]) \$coordLowestY = array(\$x, \$y);
if (\$y >= \$coordHighestY[1]) \$coordHighestY = array(\$x, \$y);

if (\$x < \$minX) \$minX = \$x;
if (\$x > \$maxX) \$maxX = \$x;

if (\$y < \$minY) \$minY = \$y;
if (\$y > \$maxY) \$maxY = \$y;
}
}
}

// This means it's a non-rotated rectangle
if ( \$coordLowestX == array(\$minX, \$minY) )
{
\$isRotated = false;

return array( array(\$minX, \$minY), array(\$maxX, \$minY), array(\$minX, \$maxY), array(\$maxX, \$maxY) );
}
// This means it's a rotated rectangle
else
{
\$isRotated = true;

// Rotated counter-clockwise
if (\$coordLowestX[1] < \$coordHighestX[1])
return array(\$coordLowestX, \$coordLowestY, \$coordHighestY, \$coordHighestX);
else // Rotated clockwise
return array(\$coordLowestY, \$coordHighestY, \$coordLowestX, \$coordHighestX);
}
}
``````