Hi,
I have a PHP script which creates an image using GD and I'm trying to read its contents with PHP. When the file physically exists on the server, I can fopen it and use fread to read it. Is there a way to get the same results with a PHP page?

Thanks

    My first thought would be to remove the "header-content: image/png" line from the PHP file I'm opening, but fread doesnt accept a URL...

      I don't understand what you're trying to do... if you create an image with the GD library, the image resource is held in a variable.

      Can you show us some code so we can see what you're trying to do?

        I'm using the fpdf library to insert an image into a pdf file. Below is the code, if $file = images/penguin.png, it works, but if I link to a GD file, $file=code.php?a=a&b=b, there is a problem with fopen.

        function _parsepng($file)
        {
        	//Extract info from a PNG file
        	$f=fopen($file,'rb');
        	if(!$f)
        		$this->Error('Can\'t open image file: '.$file);
        	//Check signature
        	if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
        		$this->Error('Not a PNG file: '.$file);
        	//Read header chunk
        	fread($f,4);
        	if(fread($f,4)!='IHDR')
        		$this->Error('Incorrect PNG file: '.$file);
        	$w=$this->_freadint($f);
        	$h=$this->_freadint($f);
        	$bpc=ord(fread($f,1));
        	if($bpc>8)
        		$this->Error('16-bit depth not supported: '.$file);
        	$ct=ord(fread($f,1));
        	if($ct==0)
        		$colspace='DeviceGray';
        	elseif($ct==2)
        		$colspace='DeviceRGB';
        	elseif($ct==3)
        		$colspace='Indexed';
        	else
        		$this->Error('Alpha channel not supported: '.$file);
        	if(ord(fread($f,1))!=0)
        		$this->Error('Unknown compression method: '.$file);
        	if(ord(fread($f,1))!=0)
        		$this->Error('Unknown filter method: '.$file);
        	if(ord(fread($f,1))!=0)
        		$this->Error('Interlacing not supported: '.$file);
        	fread($f,4);
        	$parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
        	//Scan chunks looking for palette, transparency and image data
        	$pal='';
        	$trns='';
        	$data='';
        	do
        	{
        		$n=$this->_freadint($f);
        		$type=fread($f,4);
        		if($type=='PLTE')
        		{
        			//Read palette
        			$pal=fread($f,$n);
        			fread($f,4);
        		}
        		elseif($type=='tRNS')
        		{
        			//Read transparency info
        			$t=fread($f,$n);
        			if($ct==0)
        				$trns=array(ord(substr($t,1,1)));
        			elseif($ct==2)
        				$trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
        			else
        			{
        				$pos=strpos($t,chr(0));
        				if($pos!==false)
        					$trns=array($pos);
        			}
        			fread($f,4);
        		}
        		elseif($type=='IDAT')
        		{
        			//Read image data block
        			$data.=fread($f,$n);
        			fread($f,4);
        		}
        		elseif($type=='IEND')
        			break;
        		else
        			fread($f,$n+4);
        	}
        	while($n);
        	if($colspace=='Indexed' && empty($pal))
        		$this->Error('Missing palette in '.$file);
        	fclose($f);
        	return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
        }
        

          I still get an error with that:

          Warning: fopen() [function.fopen]: URL file-access is disabled in the server configuration in /home/mysite.com/pdf/fpdf.php on line 1524

          Warning: fopen(http://www.site.com/page.php?PDF=true) [function.fopen]: failed to open stream: no suitable wrapper could be found in /home/mysite.com/pdf/fpdf.php on line 1524
          FPDF error: Can't open image file: http://www.site.com/page.php?PDF=true

            Okay, I see what's up here, my webhost disabled fopen on URLs. So they require that I use cURL. Problem is, with the script they give me, I still cannot do fread...

            <?php
            $image_url = "http://example.com/image.jpg";
            $ch = curl_init();
            $timeout = 0;
            curl_setopt ($ch, CURLOPT_URL, $image_url);
            curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
            
            // Getting binary data
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
            
            $image = curl_exec($ch);
            curl_close($ch);
            
            // output to browser
            header("Content-type: image/jpeg");
            print $image;
            ?>
            

            So I replaced the fopen($file) and made it equal to $image, but fread doesn't like that input.

              That's because $image will contain the binary image date, not a path (which your _parsepng() function is looking for).

              The simplest solution I can think of would be to make a new stream type that allows you to fopen/fread a variable as if it were a normal file stream. To do this, you'd use the [man]stream_wrapper_register/man function:

              class VariableStream {
                  // This class is provided on the manual page linked above.
                  // Copy it into your script here.
              }
              
              // Do the cURL stuff here, loading the data into $image as you have above.
              
              stream_wrapper_register("var", "VariableStream")
              
              // Run your function like this:
              $data = _parsepng('var://image');

              Haven't tried this myself; no promises that it'll work.

                I tried it, but it seems that the fread still doesn't like the input.... is there a way to test out what fread shows, by perhaps echoing the function?

                This is what I have so far (I pasted the variablestream stuff all the way at the bottom of the page):

                function _parsepngphp($file)
                {
                	//Extract info from a PNG file
                
                $image_url = $file;
                $ch = curl_init();
                $timeout = 0;
                curl_setopt ($ch, CURLOPT_URL, $image_url);
                curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
                
                // Getting binary data
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
                
                $image = curl_exec($ch);
                curl_close($ch);
                $f = $image;
                
                stream_wrapper_register("var", "VariableStream")
                    or die("Failed to register protocol");
                
                $f = fopen("var://image", "rb");
                	if(!$f)
                		$this->Error('Can\'t open image file: '.$file);
                	//Check signature
                	if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
                		$contents = fread($f,8);
                		$this->Error('Not a PNG file: '. $image);
                	}
                	//Read header chunk
                	fread($f,4);
                	if(fread($f,4)!='IHDR')
                		$this->Error('Incorrect PNG file: '.$file);
                	$w=$this->_freadint($f);
                	$h=$this->_freadint($f);
                	$bpc=ord(fread($f,1));
                	if($bpc>8)
                		$this->Error('16-bit depth not supported: '.$file);
                	$ct=ord(fread($f,1));
                	if($ct==0)
                		$colspace='DeviceGray';
                	elseif($ct==2)
                		$colspace='DeviceRGB';
                	elseif($ct==3)
                		$colspace='Indexed';
                	else
                		$this->Error('Alpha channel not supported: '.$file);
                	if(ord(fread($f,1))!=0)
                		$this->Error('Unknown compression method: '.$file);
                	if(ord(fread($f,1))!=0)
                		$this->Error('Unknown filter method: '.$file);
                	if(ord(fread($f,1))!=0)
                		$this->Error('Interlacing not supported: '.$file);
                	fread($f,4);
                	$parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
                	//Scan chunks looking for palette, transparency and image data
                	$pal='';
                	$trns='';
                	$data='';
                	do
                	{
                		$n=$this->_freadint($f);
                		$type=fread($f,4);
                		if($type=='PLTE')
                		{
                			//Read palette
                			$pal=fread($f,$n);
                			fread($f,4);
                		}
                		elseif($type=='tRNS')
                		{
                			//Read transparency info
                			$t=fread($f,$n);
                			if($ct==0)
                				$trns=array(ord(substr($t,1,1)));
                			elseif($ct==2)
                				$trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
                			else
                			{
                				$pos=strpos($t,chr(0));
                				if($pos!==false)
                					$trns=array($pos);
                			}
                			fread($f,4);
                		}
                		elseif($type=='IDAT')
                		{
                			//Read image data block
                			$data.=fread($f,$n);
                			fread($f,4);
                		}
                		elseif($type=='IEND')
                			break;
                		else
                			fread($f,$n+4);
                	}
                	while($n);
                	if($colspace=='Indexed' && empty($pal))
                		$this->Error('Missing palette in '.$file);
                	fclose($f);
                	return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
                }
                

                  I don't have the complete class you're using (e.g. I'm missing what the _freadint() function does), but one problem is that the VariableStream class can only read variables that are in the global scope. To fix this, change this:

                  $image = curl_exec($ch); 
                  curl_close($ch); 
                  $f = $image; 

                  to this:

                  global $image;
                  $image = curl_exec($ch); 
                  curl_close($ch);

                  If that doesn't work, you'll have to show me the rest of this class.

                    5 years later

                    Posiblemente puede que necesiten comentar la linea open_basedir en el php.ini y reiniciar el servicio web

                      Write a Reply...