php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80335 Imagecolorat and imagecreatefrompng glitch
Submitted: 2020-11-08 01:16 UTC Modified: 2020-11-08 01:35 UTC
From: jagja870 at school dot lu Assigned:
Status: Not a bug Package: *Graphics related
PHP Version: 7.3.24 OS: Windows 10
Private report: No CVE-ID: None
 [2020-11-08 01:16 UTC] jagja870 at school dot lu
Description:
------------
if you create an image source from an image file, with imagecreatefrompng($path)
$path leads to a png image

you will come to a bug, where if u use imagecolorat() will always return an rgb value of 0.

but if you change it to imgcreatefromstring($path) and load the png file it also won't work.
imagecolorat() only works with jpg files in the end.

Test script:
---------------
 $imageSource = file_get_contents("uploads/"."myfile.png");

        $imageSource = imagecreatefrompng($imageSource);
  for($x=0; $x<$imageX;$x++){
            for($y=0;$y<$imageY;$y++){
                $rgb = imagecolorat($imageSource, $x, $y);
}
}

Expected result:
----------------
All returns get a value of 0.

Actual result:
--------------
The actual result should have returned the rgb value of the pixel in a png file.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-11-08 01:20 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2020-11-08 01:20 UTC] requinix@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves.

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external
resources such as databases, etc. If the script requires a
database to demonstrate the issue, please make sure it creates
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

The code you posted combines file_get_contents with imagecreatefrompng. Those two will never work together. Please post the exact code you had problems with.
 [2020-11-08 01:24 UTC] jagja870 at school dot lu
-Status: Feedback +Status: Open
 [2020-11-08 01:24 UTC] jagja870 at school dot lu
Full Code working:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Trier les couleurs</title>
    <link rel="stylesheet" href="design.css">
</head>
<body>
<?php
//echo 'Please wait...';
//echo 'Uploading Files...';
// Count # of uploaded files in array
$total = count($_FILES['upload']['name']);

//echo 'Clearing Directories....';
$files = glob('uploads*'); // get all file names
foreach($files as $file){ // iterate files
    if(is_file($file))
        unlink($file); // delete file
}
// Loop through each file
for( $i=0 ; $i < $total ; $i++ ) {

    //Get the temp file path
    $tmpFilePath = $_FILES['upload']['tmp_name'][$i];

    //Make sure we have a file path
    if ($tmpFilePath != ""){
        //Setup our new file path
        $newFilePath = "./uploads/" . $_FILES['upload']['name'][$i];
        $newFilePath = substr($newFilePath, 0 , strlen($newFilePath)-4);
        $newFilePath.=".jpg";
        //Upload the file into the temp dir
        if(move_uploaded_file($tmpFilePath, $newFilePath)) {

            //Handle other code here

        }
    }
}



//echo 'Collecting Colors';
$output="<table><th>Images</th><th>R</th><th>G</th><th>B</th><th>RGB divider par 3</th>";
$fileList= scandir("uploads");
$list=[array("Image","R","G","B","RGB divider par 3")];

$ImageList=[];
foreach ($fileList as $file){

    if($file != "." && $file != ".."){
        $imagePath ="uploads/".$file;
        echo "Processing: $file<br>";
        $imageSource = file_get_contents("uploads/".$file);

        $imageSource = imagecreatefromstring($imageSource);

        $size = getimagesize($imagePath);
        $imageX = $size[0];
        $imageY = $size[1];
        $imageResult=[];
        $imageResult['R']=0;
        $imageResult['G']=0;
        $imageResult['B']=0;
        $imageResult['total']=0;


        $imageResultat=[];

        for($x=0; $x<$imageX;$x++){
            for($y=0;$y<$imageY;$y++){
                $rgb = imagecolorat($imageSource, $x, $y);

                $r = ($rgb >> 16) & 0xFF;
                $g = ($rgb >> 8) & 0xFF;
                $b = $rgb & 0xFF;
                $imageResult['R']+=$r;
                $imageResult['G']+=$g;
                $imageResult['B']+=$b;
                $imageResult['total'] += $r+$g+$b;




            }

        }
        $imageResult['R']=$imageResult['R']/($imageX*$imageY);
        $imageResult['G']=$imageResult['G']/($imageX*$imageY);
        $imageResult['B']=$imageResult['B']/($imageX*$imageY);

        $imageResult['total']=$imageResult['total']/3;


       // echo print_r($imageResult, true);
        $list[] = array($file,$imageResult['R'],$imageResult['G'],$imageResult['B'],$imageResult['total']);
        $output.="<tr><td>$file</td><td>{$imageResult['R']}</td><td>{$imageResult['G']}</td><td>{$imageResult['B']}</td><td>${imageResult['total']}</td></tr>";
        unlink("uploads/$file");
    }



}
$files = glob('uploads*'); // get all file names
foreach($files as $file){ // iterate files
    if(is_file($file))
        unlink("uploads/".$file); // delete file
}
$fp = fopen('Result.csv', 'w');



foreach ($list as $fields) {
    fputcsv($fp, $fields);
}
fclose($fp);

echo "<hr>";
echo '<p>Finished Processing files!</p><br>';
echo '<p>Get Excel file: <a href="'."Result.csv".'">Download</a></p>';
echo "<hr>";
echo $output;
?>
</body>
</html>


-----------------------
Code not working:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Trier les couleurs</title>
    <link rel="stylesheet" href="design.css">
</head>
<body>
<?php
//echo 'Please wait...';
//echo 'Uploading Files...';
// Count # of uploaded files in array
$total = count($_FILES['upload']['name']);

//echo 'Clearing Directories....';
$files = glob('uploads*'); // get all file names
foreach($files as $file){ // iterate files
    if(is_file($file))
        unlink($file); // delete file
}
// Loop through each file
for( $i=0 ; $i < $total ; $i++ ) {

    //Get the temp file path
    $tmpFilePath = $_FILES['upload']['tmp_name'][$i];

    //Make sure we have a file path
    if ($tmpFilePath != ""){
        //Setup our new file path
        $newFilePath = "./uploads/" . $_FILES['upload']['name'][$i];
        $newFilePath = substr($newFilePath, 0 , strlen($newFilePath)-4);
        $newFilePath.=".jpg";
        //Upload the file into the temp dir
        if(move_uploaded_file($tmpFilePath, $newFilePath)) {

            //Handle other code here

        }
    }
}



//echo 'Collecting Colors';
$output="<table><th>Images</th><th>R</th><th>G</th><th>B</th><th>RGB divider par 3</th>";
$fileList= scandir("uploads");
$list=[array("Image","R","G","B","RGB divider par 3")];

$ImageList=[];
foreach ($fileList as $file){

    if($file != "." && $file != ".."){
        $imagePath ="uploads/".$file;
        echo "Processing: $file<br>";
        $imageSource = file_get_contents("uploads/".$file);

        $imageSource = imagecreatefrompng($imageSource);

        $size = getimagesize($imagePath);
        $imageX = $size[0];
        $imageY = $size[1];
        $imageResult=[];
        $imageResult['R']=0;
        $imageResult['G']=0;
        $imageResult['B']=0;
        $imageResult['total']=0;


        $imageResultat=[];

        for($x=0; $x<$imageX;$x++){
            for($y=0;$y<$imageY;$y++){
                $rgb = imagecolorat($imageSource, $x, $y);

                $r = ($rgb >> 16) & 0xFF;
                $g = ($rgb >> 8) & 0xFF;
                $b = $rgb & 0xFF;
                $imageResult['R']+=$r;
                $imageResult['G']+=$g;
                $imageResult['B']+=$b;
                $imageResult['total'] += $r+$g+$b;




            }

        }
        $imageResult['R']=$imageResult['R']/($imageX*$imageY);
        $imageResult['G']=$imageResult['G']/($imageX*$imageY);
        $imageResult['B']=$imageResult['B']/($imageX*$imageY);

        $imageResult['total']=$imageResult['total']/3;


       // echo print_r($imageResult, true);
        $list[] = array($file,$imageResult['R'],$imageResult['G'],$imageResult['B'],$imageResult['total']);
        $output.="<tr><td>$file</td><td>{$imageResult['R']}</td><td>{$imageResult['G']}</td><td>{$imageResult['B']}</td><td>${imageResult['total']}</td></tr>";
        unlink("uploads/$file");
    }



}
$files = glob('uploads*'); // get all file names
foreach($files as $file){ // iterate files
    if(is_file($file))
        unlink("uploads/".$file); // delete file
}
$fp = fopen('Result.csv', 'w');



foreach ($list as $fields) {
    fputcsv($fp, $fields);
}
fclose($fp);

echo "<hr>";
echo '<p>Finished Processing files!</p><br>';
echo '<p>Get Excel file: <a href="'."Result.csv".'">Download</a></p>';
echo "<hr>";
echo $output;
?>
</body>
</html>

-------------------------------
The code which works, also only works then with jpg / jpeg
Kind regards
 [2020-11-08 01:26 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2020-11-08 01:26 UTC] requinix@php.net
Find your php.ini, set error_reporting=-1 and display_errors=on, restart your web server, and try the non-working code again. If you don't see error messages then your configuration is not correct.

When you do see error messages, consider that imagecreatefrompng wants a file path and not file contents.
 [2020-11-08 01:35 UTC] jagja870 at school dot lu
--------------------------
So I tried the code again, i found the issue,
The issuce came from a string containing the image data stream instead of a file path.

I am sorry for false calling the bug report, I didn't found the error the first time cause everything seemed fine
 [2020-11-08 02:53 UTC] ehsgegeg at egegeg dot com
even on production machines you should run error_reporting E_ALL and handle warnings and notices like fatal errors, the only difference is display_errors which should only be enabled on development machines, logging in both cases
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Nov 03 23:01:27 2024 UTC