diff --git a/README.md b/README.md index 36696823..9c92c87f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -image -===== +# Intervention Image Class Image handling and manipulation \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..d0562b8d --- /dev/null +++ b/composer.json @@ -0,0 +1,29 @@ +{ + "name": "intervention/image", + "description": "Image handling and manipulation", + "version": "0.6.0-dev", + "keywords": ["image", "gd"], + "license": "MIT", + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@olivervogel.net", + "homepage": "http://olivervogel.net/" + } + ], + "require": { + "php": ">=5.3.0", + "ext-gd": "*", + "illuminate/support": "4.0.x", + "illuminate/filesystem": "4.0.x" + }, + "autoload": { + "classmap": [ + "src/migrations" + ], + "psr-0": { + "Intervention\\Image": "src/" + } + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 00000000..8425e150 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,18 @@ + + + + + ./tests/ + + + \ No newline at end of file diff --git a/public/.gitkeep b/public/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/public/gun.jpg b/public/gun.jpg new file mode 100644 index 00000000..c295746f Binary files /dev/null and b/public/gun.jpg differ diff --git a/src/Intervention/Image/Facades/Image.php b/src/Intervention/Image/Facades/Image.php new file mode 100644 index 00000000..ed7354f1 --- /dev/null +++ b/src/Intervention/Image/Facades/Image.php @@ -0,0 +1,13 @@ +filesystem = new Filesystem; + $this->setProperties($path); + } + + public static function make($path) + { + return new Image($path); + } + + private function setProperties($path) + { + if ( ! is_null($path) && $this->filesystem->exists($path)) { + + // set file info + $info = pathinfo($path); + $this->dirname = $info['dirname']; + $this->basename = $info['basename']; + $this->extension = $info['extension']; + $this->filename = $info['filename']; + + // set image info + list($this->width, $this->height, $this->type) = @getimagesize($path); + + // set resource + switch ($this->type) { + case IMG_PNG: + case 3: + $this->resource = @imagecreatefrompng($path); + break; + + case IMG_JPG: + $this->resource = @imagecreatefromjpeg($path); + break; + + case IMG_GIF: + $this->resource = @imagecreatefromgif($path); + break; + + default: + throw new Exception("Wrong image type ({$this->type}) only use JPG, PNG or GIF images."); + break; + } + } else { + + $this->width = 1; + $this->height = 1; + $this->resource = @imagecreatetruecolor($this->width, $this->height); + } + + @imagealphablending($this->resource, false); + @imagesavealpha($this->resource, true); + } + + private function modify($dst_x , $dst_y , $src_x , $src_y , $dst_w , $dst_h , $src_w , $src_h) + { + // create new image + $image = @imagecreatetruecolor($dst_w, $dst_h); + + // copy content from resource + @imagecopyresampled($image, $this->resource, $dst_x , $dst_y , $src_x , $src_y , $dst_w , $dst_h , $src_w , $src_h); + + // set new content as recource + $this->resource = $image; + + // set new dimensions + $this->width = $dst_w; + $this->height = $dst_h; + + return $this; + } + + public function resize() + { + $args = func_get_args(); + + if (array_key_exists(0, $args) && is_array($args[0])) { + + // extract 'width' and 'height' + extract(array_only($args[0], array('width', 'height'))); + $width = isset($width) ? intval($width) : null; + $height = isset($height) ? intval($height) : null; + + if ( ! is_null($width) OR ! is_null($height)) { + // if width or height are not set, define values automatically + $width = is_null($width) ? intval($height / $this->height * $this->width) : $width; + $height = is_null($height) ? intval($width / $this->width * $this->height) : $height; + } else { + // width or height not defined (resume with original values) + throw new Exception('Width or Height needs to be defined as keys in paramater array'); + } + + } elseif (array_key_exists(0, $args) && array_key_exists(1, $args) && is_numeric($args[0]) && is_numeric($args[1])) { + $width = intval($args[0]); + $height = intval($args[1]); + } + + if (is_null($width) OR is_null($height)) { + throw new Exception('width or height needs to be defined'); + } + + // create new image in new dimensions + return $this->modify(0, 0, 0, 0, $width, $height, $this->width, $this->height); + } + + public function grab() + { + $args = func_get_args(); + + if (array_key_exists(0, $args) && is_array($args[0])) { + // extract 'width' and 'height' + extract(array_only($args[0], array('width', 'height'))); + $width = isset($width) ? intval($width) : null; + $height = isset($height) ? intval($height) : null; + + if ( ! is_null($width) OR ! is_null($height)) { + // if width or height are not set, define values automatically + $width = is_null($width) ? $height : $width; + $height = is_null($height) ? $width : $height; + } else { + // width or height not defined (resume with original values) + throw new Exception('Width or Height needs to be defined as keys in paramater array'); + } + + } elseif (array_key_exists(0, $args) && array_key_exists(1, $args) && is_numeric($args[0]) && is_numeric($args[1])) { + + $width = intval($args[0]); + $height = intval($args[1]); + + } elseif (array_key_exists(0, $args) && is_numeric($args[0])) { + + $width = intval($args[0]); + $height = intval($args[0]); + + } + + if (is_null($width) OR is_null($height)) { + throw new Exception('width or height needs to be defined'); + } + + // ausschnitt berechnen + $grab_width = $this->width; + $ratio = $grab_width / $width; + + if($height * $ratio <= $this->height) + { + $grab_height = round($height * $ratio); + $src_x = 0; + $src_y = round(($this->height - $grab_height) / 2); + } + else + { + $grab_height = $this->height; + $ratio = $grab_height / $height; + $grab_width = round($width * $ratio); + $src_x = round(($this->width - $grab_width) / 2); + $src_y = 0; + } + + // dd(array($grab_width, $grab_height)); + + return $this->modify(0, 0, $src_x, $src_y, $width, $height, $grab_width, $grab_height); + } + + public function insert($file, $pos_x = 0, $pos_y = 0) + { + $obj = is_a($file, 'Intervention\Image') ? $file : (new Image($file)); + imagecopy($this->resource, $obj->resource, $pos_x, $pos_y, 0, 0, $obj->width, $obj->height); + + return $this; + } + + public function reset() + { + $this->setProperties($this->dirname .'/'. $this->basename); + } + + private function data($type = null) + { + ob_start(); + + switch (strtolower($type)) { + case 'gif': + @imagegif($this->resource); + break; + + case 'png': + @imagepng($this->resource); + break; + + default: + case 'jpg': + case 'jpeg': + @imagejpeg($this->resource, null, 90); + break; + } + + $data = ob_get_contents(); + + ob_end_clean(); + return $data; + } + + public function save($path = null) + { + $path = is_null($path) ? ($this->dirname .'/'. $this->basename) : $path; + file_put_contents($path, $this->data($this->filesystem->extension($path))); + return $this; + } + + /* + public function render($type = 'jpg') + { + return Response::make($this->data($type), 200, + array('content-type' => $this->filesystem->mime($type))); + } + */ + + public function getFilesystem() + { + return $this->filesystem; + } + + public function __toString() + { + return $this->data(); + } +} \ No newline at end of file diff --git a/src/Intervention/Image/ImageServiceProvider.php b/src/Intervention/Image/ImageServiceProvider.php new file mode 100644 index 00000000..f487f732 --- /dev/null +++ b/src/Intervention/Image/ImageServiceProvider.php @@ -0,0 +1,46 @@ +package('intervention/image'); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { + $this->app['image'] = $this->app->share(function($app) { + return new Image; + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return array('image'); + } + +} \ No newline at end of file diff --git a/src/config/.gitkeep b/src/config/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/tests/.gitkeep b/tests/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/tests/ImageTest.php b/tests/ImageTest.php new file mode 100644 index 00000000..be865336 --- /dev/null +++ b/tests/ImageTest.php @@ -0,0 +1,131 @@ +assertInstanceOf('Illuminate\Filesystem\Filesystem', $img->getFilesystem()); + } + + public function testCreationFromFile() + { + $img = $this->getTestImage(); + $this->assertInternalType('resource', $img->resource); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 800); + $this->assertEquals($img->height, 600); + $this->assertEquals($img->dirname, 'public'); + $this->assertEquals($img->basename, 'gun.jpg'); + $this->assertEquals($img->extension, 'jpg'); + $this->assertEquals($img->filename, 'gun'); + } + + public function testResizeImage() + { + $img = $this->getTestImage(); + $img->resize(320, 240); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 320); + $this->assertEquals($img->height, 240); + + // auto height + $img = $this->getTestImage(); + $img->resize(array('width' => '320')); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 320); + $this->assertEquals($img->height, 240); + + // auto width + $img = $this->getTestImage(); + $img->resize(array('height' => '240')); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 320); + $this->assertEquals($img->height, 240); + } + + public function testGrabImage() + { + $img = $this->getTestImage(); + $img->grab(200); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 200); + $this->assertEquals($img->height, 200); + + $img = $this->getTestImage(); + $img->grab(200, 100); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 200); + $this->assertEquals($img->height, 100); + + $img = $this->getTestImage(); + $img->grab(array('width' => '320', 'height' => '100')); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 320); + $this->assertEquals($img->height, 100); + + $img = $this->getTestImage(); + $img->grab(array('width' => '100')); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 100); + $this->assertEquals($img->height, 100); + + $img = $this->getTestImage(); + $img->grab(array('height' => '100')); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 100); + $this->assertEquals($img->height, 100); + } + + public function testInsertImage() + { + $img = $this->getTestImage(); + $img->insert('public/gun.jpg', 10, 10); + $this->assertInstanceOf('Intervention\Image\Image', $img); + + } + + public function testResetImage() + { + $img = $this->getTestImage(); + $img->resize(300, 200); + $img->reset(); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 800); + $this->assertEquals($img->height, 600); + } + + public function testSaveImage() + { + $save_as = 'public/test.jpg'; + $img = $this->getTestImage(); + $img->save($save_as); + $this->assertFileExists($save_as); + @unlink($save_as); + } + + public function testStringConversion() + { + $img = $this->getTestImage(); + $img = strval($img); + $this->assertInternalType('string', $img); + } + +} \ No newline at end of file