Passed
Push — master ( 8fdb78...e82e82 )
by Matias
04:37 queued 10s
created

FaceController::hipsterize()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 75
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 53
nc 7
nop 2
dl 0
loc 75
ccs 0
cts 57
cp 0
crap 30
rs 8.7143
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2018-2020 Matias De lellis <[email protected]>
4
 *
5
 * @author Matias De lellis <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\FaceRecognition\Controller;
25
26
use OCP\Image as OCP_Image;
27
28
use OCP\IRequest;
29
use OCP\Files\IRootFolder;
30
use OCP\AppFramework\Http;
31
use OCP\AppFramework\Http\DataResponse;
32
use OCP\AppFramework\Http\JSONResponse;
33
use OCP\AppFramework\Http\DataDisplayResponse;
34
use OCP\AppFramework\Controller;
35
36
use OCA\FaceRecognition\Db\Face;
37
use OCA\FaceRecognition\Db\FaceMapper;
38
39
use OCA\FaceRecognition\Db\Image;
40
use OCA\FaceRecognition\Db\ImageMapper;
41
42
use OCA\FaceRecognition\Service\SettingsService;
43
44
class FaceController extends Controller {
45
46
	/** @var IRootFolder */
47
	private $rootFolder;
48
49
	/** @var FaceMapper */
50
	private $faceMapper;
51
52
	/** @var ImageMapper */
53
	private $imageMapper;
54
55
	/** @var SettingsService */
56
	private $settingsService;
57
58
	/** @var string */
59
	private $userId;
60
61
	public function __construct($AppName,
62
	                            IRequest        $request,
63
	                            IRootFolder     $rootFolder,
64
	                            FaceMapper      $faceMapper,
65
	                            ImageMapper     $imageMapper,
66
	                            SettingsService $settingsService,
67
	                            $UserId)
68
	{
69
		parent::__construct($AppName, $request);
70
71
		$this->rootFolder      = $rootFolder;
72
		$this->faceMapper      = $faceMapper;
73
		$this->imageMapper     = $imageMapper;
74
		$this->settingsService = $settingsService;
75
		$this->userId          = $UserId;
76
	}
77
78
	/**
79
	 * @NoAdminRequired
80
	 * @NoCSRFRequired
81
	 */
82
	public function getThumb ($id, $size) {
83
		$face = $this->faceMapper->find($id);
84
		$image = $this->imageMapper->find($this->userId, $face->getImage());
0 ignored issues
show
Bug introduced by
It seems like $face->getImage() can also be of type null; however, parameter $imageId of OCA\FaceRecognition\Db\ImageMapper::find() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

84
		$image = $this->imageMapper->find($this->userId, /** @scrutinizer ignore-type */ $face->getImage());
Loading history...
85
		$fileId = $image->getFile();
86
87
		$userFolder = $this->rootFolder->getUserFolder($this->userId);
88
		$nodes = $userFolder->getById($fileId);
89
		$file = $nodes[0];
90
91
		$ownerView = new \OC\Files\View('/'. $this->userId . '/files');
0 ignored issues
show
Bug introduced by
The type OC\Files\View was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
92
		$path = $userFolder->getRelativePath($file->getPath());
93
94
		$img = new OCP_Image();
95
		$fileName = $ownerView->getLocalFile($path);
96
		$img->loadFromFile($fileName);
97
		$img->fixOrientation();
98
99
		$x = $face->getLeft ();
100
		$y = $face->getTop ();
101
		$w = $face->getRight () - $x;
102
		$h = $face->getBottom () - $y;
103
104
		$padding = $h*0.25;
105
		$x -= $padding;
106
		$y -= $padding;
107
		$w += $padding*2;
108
		$h += $padding*2;
109
110
		if ($this->settingsService->getObfuscateFaces()) {
111
			$this->hipsterize($img, $face);
112
		}
113
114
		$img->crop($x, $y, $w, $h);
115
		$img->scaleDownToFit($size, $size);
116
117
		$resp = new DataDisplayResponse($img->data(), Http::STATUS_OK, ['Content-Type' => $img->mimeType()]);
118
		$resp->setETag((string)crc32($img->data()));
119
		$resp->cacheFor(7 * 24 * 60 * 60);
120
		$resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT')));
121
122
		return $resp;
123
	}
124
125
	private function hipsterize(&$image, &$face) {
126
		$imgResource = $image->resource();
127
128
		$landmarks = json_decode($face->getLandmarks(), true);
129
		if (count($landmarks) === 5) {
130
			$eyesX1 = $landmarks[2]['x'];
131
			$eyesY1 = $landmarks[2]['y'];
132
133
			$eyesX2 = $landmarks[0]['x'];
134
			$eyesY2 = $landmarks[0]['y'];
135
136
			$eyesXC = ($eyesX2 + $eyesX1)/2;
137
			$eyesYC = ($eyesY2 + $eyesY1)/2;
138
139
			$mustacheXC = $landmarks[4]['x'];
140
			$mustacheYC = $landmarks[4]['y'];
141
		}
142
		else if (count($landmarks) === 68) {
143
			$eyesX1 = $landmarks[36]['x'];
144
			$eyesY1 = $landmarks[36]['y'];
145
			$eyesX2 = $landmarks[45]['x'];
146
			$eyesY2 = $landmarks[45]['y'];
147
148
			$eyesXC = ($eyesX2 + $eyesX1)/2;
149
			$eyesYC = ($eyesY2 + $eyesY1)/2;
150
151
			$mustacheXC = $landmarks[52]['x'];
152
			$mustacheYC = $landmarks[52]['y'];
153
		}
154
		else {
155
			return;
156
		}
157
158
		$eyesW = $eyesX2 - $eyesX1;
159
		$eyesH = $eyesY2 - $eyesY1;
160
161
		$eyesL = sqrt(pow($eyesW, 2) + pow($eyesH, 2));
162
		$angle = rad2deg(atan(-$eyesH/$eyesW));
163
164
		$glassesGd = imagecreatefrompng(\OC_App::getAppPath('facerecognition') . '/img/glasses.png');
0 ignored issues
show
Bug introduced by
The type OC_App was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
165
		if ($glassesGd === false)
166
			return;
167
		$fillColor = imagecolorallocatealpha($glassesGd, 0, 0, 0, 127);
168
		$glassesGd = imagerotate($glassesGd, $angle, $fillColor);
169
170
		$glassesW = imagesx($glassesGd);
0 ignored issues
show
Bug introduced by
It seems like $glassesGd can also be of type false; however, parameter $image of imagesx() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
		$glassesW = imagesx(/** @scrutinizer ignore-type */ $glassesGd);
Loading history...
171
		$glassesH = imagesy($glassesGd);
0 ignored issues
show
Bug introduced by
It seems like $glassesGd can also be of type false; however, parameter $image of imagesy() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

171
		$glassesH = imagesy(/** @scrutinizer ignore-type */ $glassesGd);
Loading history...
172
173
		$glassesRatio = $eyesL/$glassesW*1.5;
174
175
		$glassesDestX = intval($eyesXC - $glassesW * $glassesRatio / 2);
176
		$glassesDestY = intval($eyesYC - $glassesH * $glassesRatio / 2);
177
		$glassesDestW = intval($glassesW * $glassesRatio);
178
		$glassesDestH = intval($glassesH * $glassesRatio);
179
180
		imagecopyresized($imgResource, $glassesGd, $glassesDestX, $glassesDestY, 0, 0, $glassesDestW, $glassesDestH, $glassesW, $glassesH);
0 ignored issues
show
Bug introduced by
It seems like $glassesGd can also be of type false; however, parameter $src_image of imagecopyresized() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

180
		imagecopyresized($imgResource, /** @scrutinizer ignore-type */ $glassesGd, $glassesDestX, $glassesDestY, 0, 0, $glassesDestW, $glassesDestH, $glassesW, $glassesH);
Loading history...
181
182
		$mustacheGd = imagecreatefrompng(\OC_App::getAppPath('facerecognition') . '/img/mustache.png');
183
		if ($mustacheGd === false)
184
			return;
185
		$fillColor = imagecolorallocatealpha($mustacheGd, 0, 0, 0, 127);
186
		$mustacheGd = imagerotate($mustacheGd, $angle, $fillColor);
187
		$mustacheW = imagesx($mustacheGd);
188
		$mustacheH = imagesy($mustacheGd);
189
190
		$mustacheRatio = $eyesL/$glassesW*1.1;
191
192
		$mustacheDestX = intval($mustacheXC - $mustacheW * $mustacheRatio / 2);
193
		$mustacheDestY = intval($mustacheYC - $mustacheH * $mustacheRatio / 2);
194
		$mustacheDestW = intval($mustacheW * $mustacheRatio);
195
		$mustacheDestH = intval($mustacheH * $mustacheRatio);
196
197
		imagecopyresized($imgResource, $mustacheGd, $mustacheDestX, $mustacheDestY, 0, 0, $mustacheDestW, $mustacheDestH, $mustacheW, $mustacheH);
198
199
		$image->setResource($imgResource);
200
	}
201
202
}
203