Completed
Push — master ( 6b7d3b...36f68c )
by Aimeos
10:40
created

Standard::resample()   C

Complexity

Conditions 7
Paths 10

Size

Total Lines 32
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 16
nc 10
nop 5
dl 0
loc 32
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright Metaways Infosystems GmbH, 2014
5
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
6
 * @copyright Aimeos (aimeos.org), 2015-2017
7
 * @package MW
8
 * @subpackage Media
9
 */
10
11
12
namespace Aimeos\MW\Media\Image;
13
14
15
/**
16
 * Default image class using GDLib.
17
 *
18
 * @package MW
19
 * @subpackage Media
20
 */
21
class Standard
22
	extends \Aimeos\MW\Media\Image\Base
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces between "Base" and comma; 1 found
Loading history...
23
	implements \Aimeos\MW\Media\Image\Iface
24
{
25
	private $info;
26
	private $image;
27
	private $origimage;
28
	private $options;
29
30
31
	/**
32
	 * Initializes the new image object.
33
	 *
34
	 * @param string $content File content
35
	 * @param string $mimetype Mime type of the media data
36
	 * @param array $options Associative list of configuration options
37
	 * @throws \Aimeos\MW\Media\Exception If image couldn't be retrieved from the given file name
38
	 */
39
	public function __construct( $content, $mimetype, array $options )
40
	{
41
		parent::__construct( $mimetype );
42
43
		if( ( $this->image = @imagecreatefromstring( $content ) ) === false ) {
44
			throw new \Aimeos\MW\Media\Exception( sprintf( 'The image type isn\'t supported by GDlib.') );
45
		}
46
47
		if( ( $this->info = getimagesizefromstring( $content ) ) === false ) {
48
			throw new \Aimeos\MW\Media\Exception( sprintf( 'Unable to retrieve image size' ) );
49
		}
50
51
		if( imagealphablending( $this->image, false ) === false ) {
52
			throw new \Aimeos\MW\Media\Exception( sprintf( 'GD library failed (imagealphablending)') );
53
		}
54
55
		$this->options = $options;
56
	}
57
58
59
	/**
60
	 * Cleans up
61
	 */
62
	public function __destruct()
63
	{
64
		if( $this->origimage ) {
65
			imagedestroy( $this->origimage );
66
		}
67
68
		if( $this->image ) {
69
			imagedestroy( $this->image );
70
		}
71
	}
72
73
74
	/**
75
	 * Stores the media data at the given file name.
76
	 *
77
	 * @param string|null $filename File name to save the data into or null to return the data
78
	 * @param string|null $mimetype Mime type to save the content as or null to leave the mime type unchanged
79
	 * @return string|null File content if file name is null or null if data is saved to the given file name
80
	 * @throws \Aimeos\MW\Media\Exception If image couldn't be saved to the given file name
81
	 */
82
	public function save( $filename = null, $mimetype = null )
83
	{
84
		if( $mimetype === null ) {
85
			$mimetype = $this->getMimeType();
86
		}
87
88
		$quality = 90;
89
		if( isset( $this->options['image']['quality'] ) ) {
90
			$quality = max( min( (int) $this->options['image']['quality'], 100 ), 0 );
91
		}
92
93
		try
94
		{
95
			ob_start();
96
97
			switch( $mimetype )
98
			{
99
				case 'image/gif':
100
101
					if( @imagegif( $this->image, $filename ) === false ) {
102
						throw new \Aimeos\MW\Media\Exception( sprintf( 'Unable to save image to file "%1$s"', $filename ) );
103
					}
104
105
					break;
106
107
				case 'image/jpeg':
108
109
					if( @imagejpeg( $this->image, $filename, $quality ) === false ) {
110
						throw new \Aimeos\MW\Media\Exception( sprintf( 'Unable to save image to file "%1$s"', $filename ) );
111
					}
112
113
					break;
114
115
				case 'image/png':
116
117
					if( imagesavealpha( $this->image, true ) === false ) {
118
						throw new \Aimeos\MW\Media\Exception( sprintf( 'GD library failed (imagesavealpha)') );
119
					}
120
121
					if( @imagepng( $this->image, $filename, (int) 10 - $quality / 10 ) === false ) {
122
						throw new \Aimeos\MW\Media\Exception( sprintf( 'Unable to save image to file "%1$s"', $filename ) );
123
					}
124
125
					break;
126
127
				default:
128
					throw new \Aimeos\MW\Media\Exception( sprintf( 'File format "%1$s" is not supported', $this->getMimeType() ) );
129
			}
130
131
			if( $filename === null ) {
132
				return ob_get_clean();
133
			}
134
		}
135
		catch( \Exception $e )
136
		{
137
			ob_end_clean();
138
			throw $e;
139
		}
140
	}
141
142
143
	/**
144
	 * Scales the image to the given width and height.
145
	 *
146
	 * @param integer $width New width of the image
147
	 * @param integer $height New height of the image
148
	 * @param boolean $fit True to keep the width/height ratio of the image
149
	 * @return \Aimeos\MW\Media\Iface Self object for method chaining
150
	 */
151
	public function scale( $width, $height, $fit = true )
152
	{
153
		if( $fit === true )
154
		{
155
			list( $width, $height ) = $this->getSizeFitted( $this->info[0], $this->info[1], $width, $height );
156
157
			if( $this->info[0] <= $width && $this->info[1] <= $height ) {
158
				return $this;
159
			}
160
		}
161
162
		if( function_exists( 'imagescale' ) === true )
163
		{
164
			if( ( $result = imagescale( $this->image, $width, $height, IMG_BICUBIC ) ) === false ) {
165
				throw new \Aimeos\MW\Media\Exception( 'Unable to scale image' );
166
			}
167
168
			$this->image = $result;
169
		}
170
		else
171
		{
172
			$this->image = $this->resample( $this->image, $this->info[0], $this->info[1], $width, $height );
173
		}
174
175
		$this->info[0] = $width;
176
		$this->info[1] = $height;
177
178
		return $this;
179
	}
180
181
182
	/**
183
	 * Resamples the image to the given width and height.
184
	 *
185
	 * @param resource GDlib image object
186
	 * @param integer $srcWidth Width of the existing image
187
	 * @param integer $srcHeight Height of the existing image
188
	 * @param integer $destWidth Width of the new image
189
	 * @param integer $destHeight Height of the new image
190
	 * @return resource New GDlib image object
191
	 */
192
	protected function resample( $image, $srcWidth, $srcHeight, $destWidth, $destHeight )
193
	{
194
		if( ( $newImage = imagecreatetruecolor( $destWidth, $destHeight ) ) === false ) {
195
			throw new \Aimeos\MW\Media\Exception( 'Unable to create new image' );
196
		}
197
198
		try
199
		{
200
			if( imagealphablending( $newImage, false ) === false ) {
201
				throw new \Aimeos\MW\Media\Exception( sprintf( 'GD library failed (imagealphablending)') );
202
			}
203
204
			if( ( $transparent = imagecolorallocatealpha( $newImage, 255, 255, 255, 127 ) ) === false ) {
205
				throw new \Aimeos\MW\Media\Exception( sprintf( 'GD library failed (imagecolorallocatealpha)') );
206
			}
207
208
			if( imagefilledrectangle( $newImage, 0, 0, $destWidth, $destHeight, $transparent ) === false ) {
209
				throw new \Aimeos\MW\Media\Exception( sprintf( 'GD library failed (imagefilledrectangle)') );
210
			}
211
212
			if( imagecopyresampled( $newImage, $image, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight ) === false ) {
213
				throw new \Aimeos\MW\Media\Exception( 'Unable to resize image' );
214
			}
215
		}
216
		catch( \Exception $e )
217
		{
218
			imagedestroy( $newImage );
219
			throw $e;
220
		}
221
222
		return $newImage;
223
	}
224
}
225