PDF Viewer


(Cbimax) #1

Hello there!

Due to secure reasons, the customer want an internal pdf viewer like Google pdf viewer.

I have been working in a viewer that uses ghostscript to render document’ pages, but I need to build the right panel minimized slides.

I want to implement jQuery lazy load in order to render only the visible slides.

Is there a possible way to implement a view with frames? So, in a 1-column way will be a central frame with the current pdf’s page rendered, and a right frame with the list of little slides?

Really appreciate any feedback,

cbi

ps: perhaps, there is a solution/module in Yii going around that not requiere Acrobat to be installed?


(Jzhong5) #2

Did you solve that problem…?

I need to solve the same question now…


(Jzhong5) #3

any ideas?


(Cbimax) #4

Yes; having use [font=“Courier New”]ghostscript[/font] and some ajax to render images and page’ snapshots from pdf file.

In fact, here it is the Controller which calls [font="Courier New"]gs[/font]:


class ImageController extends RController

{

	protected $image;

	protected $image_type;




	public function actionIndex( $file, $resize = Null, $resizeToWidth = Null, $page = 1 )

	{

		if( $file )

		{

			ob_end_clean();


			$filename = Yii::app()->basePath . '/data/' . $file;


			if( strtolower( pathinfo( $filename, PATHINFO_EXTENSION ) ) == 'pdf' )

			{

				if( empty( $resize ) )

					$resize = '10x10';


		    	if( !is_dir( '/tmp/' . Yii::app()->getRequest()->getServerName() . '/' ) )

    				$status = mkdir( '/tmp/' . Yii::app()->getRequest()->getServerName() . '/', 0777, True );


				$output = '/tmp/' . Yii::app()->getRequest()->getServerName() . '/' . md5( $filename . $resize . $page ) . '.jpeg';


				if( !is_file( $output ) )

					exec( "gs -dNOPAUSE -dPARANOIDSAFER -dBufferSpace=1000000000 -dBandHeight=100 -dBandBufferSpace=500000000 -dBATCH -dQUIET -sDEVICE=jpeg -dNOGC -dNumRenderingThreads=4 -dFirstPage=$page -dLastPage=$page -r$resize -sOutputFile=$output '$filename'" );


				$resize = Null;

				$resizeToWidth = Null;

				$filename = $output;

			}


			$this->loadImage( $filename );


			if( !empty( $resize ) )

			{

				$resize = explode( 'x', $resize, 2 );


   				$this->resize( (int) $resize[0], (int) $resize[1] );

			}

			elseif( !empty( $resizeToWidth ) )

				$this->resizeToWidth( (int) $resizeToWidth );


			$this->output();


			Yii::app()->end();

		}

	}


	protected function loadImage( $filename )

	{

		$image_info = getimagesize($filename);


		$this->image_type = $image_info[2];


		if( $this->image_type == IMAGETYPE_JPEG )

			$this->image = imagecreatefromjpeg($filename);

		elseif( $this->image_type == IMAGETYPE_GIF )

			$this->image = imagecreatefromgif($filename);

		elseif( $this->image_type == IMAGETYPE_PNG )

			$this->image = imagecreatefrompng($filename);


	}


	protected function saveImage( $filename, $image_type = IMAGETYPE_JPEG, $compression= 75, $permissions = Null )

	{

		if( $image_type == IMAGETYPE_JPEG )

			imagejpeg( $this->image, $filename, $compression);

		elseif( $image_type == IMAGETYPE_GIF )

			imagegif($this->image,$filename);

		elseif( $image_type == IMAGETYPE_PNG )

			imagepng($this->image,$filename);


		if( $permissions!= null )

			chmod( $filename, $permissions );


	}


	protected function output( $image_type = IMAGETYPE_JPEG )

	{

		if( $image_type == IMAGETYPE_JPEG )

		{

			header( "Content-type: image/jpeg");

			imagejpeg($this->image);

		}

		elseif( $image_type == IMAGETYPE_GIF )

		{

			header( "Content-type: image/gif");

			imagegif($this->image);

		}

		elseif( $image_type == IMAGETYPE_PNG )

		{

			header( "Content-type: image/png");

			imagepng($this->image);

		}

	}


	protected function getWidth()

	{

		return imagesx($this->image);

	}


	protected function getHeight()

	{

		return imagesy($this->image);

	}


	protected function resizeToHeight($height)

	{

		$ratio = $height / $this->getHeight();

		$width = $this->getWidth() * $ratio;


		$this->resize($width,$height);

	}


	protected function resizeToWidth($width)

	{

		$ratio = $width / $this->getWidth();

		$height = $this->getheight() * $ratio;


		$this->resize($width,$height);

	}


	protected function scale($scale)

	{

		$width = $this->getWidth() * $scale/100;

		$height = $this->getheight() * $scale/100;


		$this->resize($width,$height);

	}


	protected function resize($width,$height)

	{

		$new_image = imagecreatetruecolor($width, $height);

		imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());

		$this->image = $new_image;

	}

}



For views’ layouts I use [font=“Courier New”]jquery.waypoints[/font] and [font=“Courier New”]jquery.layout[/font] scripts. The first script helps in order to make a lazy loader for the images, the second provides a framework for the layout (north, center, left, south) of the screen.

cbi


(Rodzadra) #5

Do you know the Djvu file format?

http://djvu.org/

In the past, i have made something similar to what you did, but using the Djvu file format and the Djvu browser plugin.

Of course, what you did is most (or more?) modern and doesn’t need a browser plugin. =)


(Cbimax) #6

No, I didn’t know it. Thanks for the tip.

The pdf viewer was part of an archive module; the pdf files come from the office scanner which is configured to resize, align and compress every page on the (real) folder.

There where some issues with the speed of [font="Courier New"]ghostscript[/font]; the [font="Courier New"]gs[/font] command at the controller, comes after a few months of research…

Best,

cbi


(Dev Madand) #7

Hi all!

I’ve solved similar problem, some time ago, using FlexPaper. In that time it was Flash/Flex only solution, but as i see, now there is also support for HTML5.

Maybe someone will find it useful too.


(Ethel S. Wunder) #8

This post was flagged by the community and is temporarily hidden.