Passed
Push — master ( 132edd...186cf7 )
by Matias
21:30 queued 04:34
created

TempImage::getTempPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * @copyright Copyright (c) 2018-2019 Branko Kokanovic <[email protected]>
5
 * @copyright Copyright (c) 2018-2020 Matias De lellis <[email protected]>
6
 *
7
 * @author Branko Kokanovic <[email protected]>
8
 *
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
namespace OCA\FaceRecognition\Helper;
26
27
use OCP\Image;
28
use OCP\ILogger;
29
use OCP\ITempManager;
30
31
class TempImage extends Image {
32
33
	/** @var string */
34
	private $imagePath;
35
36
	/** @var string */
37
	private $tempPath;
38
39
	/** @var string */
40
	private $preferredMimeType;
41
42
	/** @var int */
43
	private $maxImageArea;
44
45
	/** @var ITempManager */
46
	private $tempManager;
47
48
	/** @var int */
49
	private $minImageSide;
50
51
	/** @var float */
52
	private $ratio = -1.0;
53
54
	/** @var bool */
55
	private $skipped = false;
56
57 5
	public function __construct(string $imagePath,
58
	                            string $preferredMimeType,
59
	                            int    $maxImageArea,
60
	                            int    $minImageSide)
61
	{
62 5
		parent::__construct();
63
64 5
		$this->imagePath         = $imagePath;
65 5
		$this->preferredMimeType = $preferredMimeType;
66 5
		$this->maxImageArea      = $maxImageArea;
67 5
		$this->minImageSide      = $minImageSide;
68
69 5
		$this->tempManager       = \OC::$server->getTempManager();
70
71 5
		$this->prepareImage();
72 4
	}
73
74
	/**
75
	 * Get the path of temporary image
76
	 *
77
	 * @return string
78
	 */
79 3
	public function getTempPath(): string {
80 3
		return $this->tempPath;
81
	}
82
83
	/**
84
	 * Obtain the ratio of the temporary image against the original
85
	 *
86
	 * @return float
87
	 */
88 2
	public function getRatio(): float {
89 2
		return $this->ratio;
90
	}
91
92
	/** Return if image was skipped
93
	 *
94
	 * @return bool
95
	 */
96 4
	public function getSkipped(): bool {
97 4
		return $this->skipped;
98
	}
99
100
	/**
101
	 * Clean temporary files
102
	 */
103 4
	public function clean() {
104 4
		$this->tempManager->clean();
105 4
	}
106
107
	/**
108
	 * Obtain a temporary image according to the imposed restrictions.
109
	 *
110
	 */
111 5
	private function prepareImage() {
112 5
		$this->loadFromFile($this->imagePath);
113 4
		$this->fixOrientation();
114
115 4
		if (!$this->valid()) {
116
			throw new \RuntimeException("Image is not valid, probably cannot be loaded");
117
		}
118
119 4
		if ((imagesx($this->resource()) < $this->minImageSide) ||
120 4
		    (imagesy($this->resource()) < $this->minImageSide)) {
121 2
			$this->skipped = true;
122 2
			return;
123
		}
124
125 3
		$this->ratio = $this->resizeImage();
126 3
		$this->tempPath = $this->tempManager->getTemporaryFile();
127
128 3
		$this->save($this->tempPath, $this->preferredMimeType);
129 3
	}
130
131
	/**
132
	 * Resizes the image to reach max image area, but preserving ratio.
133
	 *
134
	 * @return float Ratio of resize. 1 if there was no resize
135
	 */
136 3
	private function resizeImage(): float {
137 3
		$widthOrig = imagesx($this->resource());
138 3
		$heightOrig = imagesy($this->resource());
139
140 3
		if (($widthOrig <= 0) || ($heightOrig <= 0)) {
141
			$message = "Image is having non-positive width or height, cannot continue";
142
			throw new \RuntimeException($message);
143
		}
144
145 3
		$areaRatio = $this->maxImageArea / ($widthOrig * $heightOrig);
146 3
		$scaleFactor = sqrt($areaRatio);
147
148 3
		$newWidth = intval(round($widthOrig * $scaleFactor));
149 3
		$newHeight = intval(round($heightOrig * $scaleFactor));
150
151 3
		$success = $this->preciseResize($newWidth, $newHeight);
152 3
		if ($success === false) {
153
			throw new \RuntimeException("Error during image resize");
154
		}
155
156 3
		return 1 / $scaleFactor;
157
	}
158
159
}