PageRenderTime 25ms CodeModel.GetById 12ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/library/html2pdf/_mypdf/03_fpdf_alpha.class.php

https://bitbucket.org/DenizYldrm/openemr
PHP | 327 lines | 246 code | 29 blank | 52 comment | 47 complexity | 8ea98ac3549289604908d1f22581be3b MD5 | raw file
  1<?php
  2/*************************************************************************
  3 * http://staff.dasdeck.de/valentin/fpdf/fpdf_alpha/
  4 * 
  5 * @author		Valentin Schmidt
  6 * 
  7 * This script allows to use images (PNGs or JPGs) with alpha-channels.
  8 * The alpha-channel can be either supplied as separate 8-bit PNG ("mask"),
  9 * or, for PNGs, also an internal alpha-channel can be used.
 10 * For the latter, the GD 2.x extension is required.
 11 ************************************************************************/
 12
 13
 14if (!defined('__CLASS_FPDF_ALPHA__'))
 15{
 16	define('__CLASS_FPDF_ALPHA__', true);
 17	
 18	require_once(dirname(__FILE__).'/02_fpdf_formulaire.class.php');
 19	
 20	class FPDF_Alpha extends FPDF_Formulaire
 21	{
 22		var $tmpFiles = array(); 
 23		
 24		function FPDF_Alpha($orientation='P',$unit='mm',$format='A4')
 25		{
 26			$this->FPDF_Formulaire($orientation,$unit,$format);
 27		}
 28		
 29		/* Public methods */
 30		function Image($file,$x,$y,$w=0,$h=0,$type='',$link='', $isMask=false, $maskImg=0)
 31		{
 32			//Put an image on the page
 33			if(!isset($this->images[$file]))
 34			{
 35				//First use of image, get info
 36				if($type=='')
 37				{
 38					/* MODIFICATION HTML2PDF pour le support des images g�n�r�es */
 39					$type = explode('?', $file);
 40					$type = pathinfo($type[0]);
 41					if (!isset($type['extension']) || !$type['extension'])
 42						$type['extension'] = 'php';
 43//						$this->Error('Image file has no extension and no type was specified: '.$file);
 44						
 45					$type = $type['extension'];
 46					/* FIN MODIFICATION */
 47/*
 48					$pos=strrpos($file,'.');
 49					if(!$pos)
 50						$this->Error('Image file has no extension and no type was specified: '.$file);
 51					$type=substr($file,$pos+1);
 52*/
 53				}
 54				$type=strtolower($type);
 55
 56				/* MODIFICATION HTML2PDF pour le support des images g�n�r�es */
 57				if ($type=='php' || $type=='cgi')
 58				{
 59					// identification des infos
 60					$infos=@GetImageSize($file);
 61					if (!$infos) $this->Error('Unsupported image : '.$file);
 62				
 63					// identification du type
 64					$type = explode('/', $infos['mime']);
 65					if ($type[0]!='image') $this->Error('Unsupported image : '.$file);
 66					$type = $type[1];
 67				}
 68				/* FIN MODIFICATION */
 69				
 70//				$mqr=get_magic_quotes_runtime();
 71//				set_magic_quotes_runtime(0);
 72				if($type=='jpg' || $type=='jpeg')
 73					$info=$this->_parsejpg($file);
 74				elseif($type=='png')
 75				{
 76					$info=$this->_parsepng($file);
 77					if ($info=='alpha')
 78						return $this->ImagePngWithAlpha($file,$x,$y,$w,$h,$link);
 79				}
 80				else
 81				{
 82					//Allow for additional formats
 83					$mtd='_parse'.$type;
 84					if(!method_exists($this,$mtd))
 85					$this->Error('Unsupported image type: '.$type);
 86					$info=$this->$mtd($file);
 87				}
 88//				set_magic_quotes_runtime($mqr);
 89			
 90				if ($isMask)
 91				{
 92					$info['cs']="DeviceGray"; // try to force grayscale (instead of indexed)
 93				}
 94				$info['i']=count($this->images)+1;
 95				if ($maskImg>0) $info['masked'] = $maskImg;###
 96				$this->images[$file]=$info;
 97			}
 98			else
 99				$info=$this->images[$file];
100				
101			//Automatic width and height calculation if needed
102			if($w==0 && $h==0)
103			{
104				//Put image at 72 dpi
105				$w=$info['w']/$this->k;
106				$h=$info['h']/$this->k;
107			}
108			if($w==0)
109				$w=$h*$info['w']/$info['h'];
110			if($h==0)
111				$h=$w*$info['h']/$info['w'];
112		
113			if ($isMask) // embed hidden, ouside the canvas
114			{
115				$x = ($this->CurOrientation=='P'?$this->CurPageFormat[0]*2:$this->CurPageFormat[1]*2) + 10; 
116			}
117			else // modification by spipu :) pas besoin de tracer l'image si c'est pour faire un mask !!!!
118			{
119				$this->_out(sprintf('q %.2F 0 0 %.2F %.2F %.2F cm /I%d Do Q',$w*$this->k,$h*$this->k,$x*$this->k,($this->h-($y+$h))*$this->k,$info['i']));
120				if($link) $this->Link($x,$y,$w,$h,$link);
121			}
122		
123			return $info['i'];
124		}
125
126		// needs GD 2.x extension
127		// pixel-wise operation, not very fast
128		function ImagePngWithAlpha($file,$x,$y,$w=0,$h=0,$link='')
129		{
130			$tmp_alpha = tempnam(null, 'mska');
131			$this->tmpFiles[] = $tmp_alpha;
132			$tmp_plain = tempnam(null, 'mskp');
133			$this->tmpFiles[] = $tmp_plain;
134		
135			list($wpx, $hpx) = @getimagesize($file);
136			$img = imagecreatefrompng($file);
137			$alpha_img = imagecreate( $wpx, $hpx );
138		
139			// generate gray scale pallete
140			for($c=0;$c<256;$c++) ImageColorAllocate($alpha_img, $c, $c, $c);
141			
142			// extract alpha channel
143			$xpx=0;
144			while ($xpx<$wpx)
145			{
146				$ypx = 0;
147				while ($ypx<$hpx)
148				{
149					$color_index = imagecolorat($img, $xpx, $ypx);
150					$col = imagecolorsforindex($img, $color_index);
151					imagesetpixel($alpha_img, $xpx, $ypx, $this->_gamma( (127-$col['alpha'])*255/127) );
152					++$ypx;
153				}
154				++$xpx;
155			}
156		
157			imagepng($alpha_img, $tmp_alpha);
158			imagedestroy($alpha_img);
159		
160			// extract image without alpha channel
161			$plain_img = imagecreatetruecolor ( $wpx, $hpx );
162			imagecopy ($plain_img, $img, 0, 0, 0, 0, $wpx, $hpx );
163			imagepng($plain_img, $tmp_plain);
164			imagedestroy($plain_img);
165		
166			//first embed mask image (w, h, x, will be ignored)
167			$maskImg = $this->Image($tmp_alpha, 0,0,0,0, 'PNG', '', true);
168			
169			//embed image, masked with previously embedded mask
170			$this->Image($tmp_plain,$x,$y,$w,$h,'PNG',$link, false, $maskImg);
171		}
172	
173		function Close()
174		{
175			parent::Close();
176			// clean up tmp files
177			foreach($this->tmpFiles as $tmp) @unlink($tmp);
178		}
179
180		/* Private methods */
181		function _putimages()
182		{
183			$filter=($this->compress) ? '/Filter /FlateDecode ' : '';
184			reset($this->images);
185			while(list($file,$info)=each($this->images))
186			{
187				$this->_newobj();
188				$this->images[$file]['n']=$this->n;
189				$this->_out('<</Type /XObject');
190				$this->_out('/Subtype /Image');
191				$this->_out('/Width '.$info['w']);
192				$this->_out('/Height '.$info['h']);
193		
194				if (isset($info["masked"])) $this->_out('/SMask '.($this->n-1).' 0 R'); ###
195				
196				if($info['cs']=='Indexed')
197				$this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
198				else
199				{
200					$this->_out('/ColorSpace /'.$info['cs']);
201					if($info['cs']=='DeviceCMYK')
202					$this->_out('/Decode [1 0 1 0 1 0 1 0]');
203				}
204				$this->_out('/BitsPerComponent '.$info['bpc']);
205				if(isset($info['f']))
206				$this->_out('/Filter /'.$info['f']);
207				if(isset($info['parms']))
208				$this->_out($info['parms']);
209				if(isset($info['trns']) && is_array($info['trns']))
210				{
211					$trns='';
212					for($i=0;$i<count($info['trns']);$i++)
213					$trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
214					$this->_out('/Mask ['.$trns.']');
215				}
216				$this->_out('/Length '.strlen($info['data']).'>>');
217				$this->_putstream($info['data']);
218				unset($this->images[$file]['data']);
219				$this->_out('endobj');
220				//Palette
221				if($info['cs']=='Indexed')
222				{
223					$this->_newobj();
224					$pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
225					$this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
226					$this->_putstream($pal);
227					$this->_out('endobj');
228				}
229			}
230		}
231
232		// GD seems to use a different gamma, this method is used to correct it again
233		function _gamma($v)
234		{
235			return pow ($v/255, 2.2) * 255;
236		}
237
238		// this method overwriing the original version is only needed to make the Image method support PNGs with alpha channels.
239		// if you only use the ImagePngWithAlpha method for such PNGs, you can remove it from this script.
240		function _parsepng($file)
241		{
242			//Extract info from a PNG file
243			$f=fopen($file,'rb');
244			if(!$f)
245				$this->Error('Can\'t open image file: '.$file);
246			//Check signature
247			if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
248				$this->Error('Not a PNG file: '.$file);
249			//Read header chunk
250			fread($f,4);
251			if(fread($f,4)!='IHDR')
252				$this->Error('Incorrect PNG file: '.$file);
253			$w=$this->_readint($f);
254			$h=$this->_readint($f);
255			$bpc=ord(fread($f,1));
256			if($bpc>8)
257				$this->Error('16-bit depth not supported: '.$file);
258			$ct=ord(fread($f,1));
259			if($ct==0)
260				$colspace='DeviceGray';
261			elseif($ct==2)
262				$colspace='DeviceRGB';
263			elseif($ct==3)
264				$colspace='Indexed';
265			else
266			{
267				fclose($f);		// the only changes are
268				return 'alpha';	// made in those 2 lines
269			}
270			if(ord(fread($f,1))!=0)
271				$this->Error('Unknown compression method: '.$file);
272			if(ord(fread($f,1))!=0)
273				$this->Error('Unknown filter method: '.$file);
274			if(ord(fread($f,1))!=0)
275				$this->Error('Interlacing not supported: '.$file);
276			fread($f,4);
277			$parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
278			//Scan chunks looking for palette, transparency and image data
279			$pal='';
280			$trns='';
281			$data='';
282			do
283			{
284				$n=$this->_readint($f);
285				$type=fread($f,4);
286				if($type=='PLTE')
287				{
288					//Read palette
289					$pal=fread($f,$n);
290					fread($f,4);
291				}
292				elseif($type=='tRNS')
293				{
294					//Read transparency info
295					$t=fread($f,$n);
296					if($ct==0)
297						$trns=array(ord(substr($t,1,1)));
298					elseif($ct==2)
299						$trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
300					else
301					{
302						$pos=strpos($t,chr(0));
303						if($pos!==false)
304							$trns=array($pos);
305					}
306					fread($f,4);
307				}
308				elseif($type=='IDAT')
309				{
310					//Read image data block
311					$data.=fread($f,$n);
312					fread($f,4);
313				}
314				elseif($type=='IEND')
315					break;
316				else
317					fread($f,$n+4);
318			}
319			while($n);
320			if($colspace=='Indexed' && empty($pal))
321				$this->Error('Missing palette in '.$file);
322			fclose($f);
323			return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
324		} 
325		
326	}
327}