Issues (125)

lib/Controller/FaceController.php (3 issues)

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 OCP\AppFramework\Db\Entity;
37
38
use OCA\FaceRecognition\Db\Face;
39
use OCA\FaceRecognition\Db\FaceMapper;
40
41
use OCA\FaceRecognition\Db\Image;
42
use OCA\FaceRecognition\Db\ImageMapper;
43
44
use OCA\FaceRecognition\Service\SettingsService;
45
46
class FaceController extends Controller {
47
48
	/** @var IRootFolder */
49
	private $rootFolder;
50
51
	/** @var FaceMapper */
52
	private $faceMapper;
53
54
	/** @var ImageMapper */
55
	private $imageMapper;
56
57
	/** @var SettingsService */
58
	private $settingsService;
59
60
	/** @var string */
61
	private $userId;
62
63
	public function __construct($AppName,
64
	                            IRequest        $request,
65
	                            IRootFolder     $rootFolder,
66
	                            FaceMapper      $faceMapper,
67
	                            ImageMapper     $imageMapper,
68
	                            SettingsService $settingsService,
69
	                            $UserId)
70
	{
71
		parent::__construct($AppName, $request);
72
73
		$this->rootFolder      = $rootFolder;
74
		$this->faceMapper      = $faceMapper;
75
		$this->imageMapper     = $imageMapper;
76
		$this->settingsService = $settingsService;
77
		$this->userId          = $UserId;
78
	}
79
80
	/**
81
	 * @NoAdminRequired
82
	 *
83
	 * @NoCSRFRequired
84
	 *
85
	 * @return DataDisplayResponse|JSONResponse
86
	 */
87
	public function getThumb ($id, $size) {
88
		$face = $this->faceMapper->find($id);
89
		if ($face === null) {
90
			return new JSONResponse([], Http::STATUS_NOT_FOUND);
91
		}
92
93
		$image = $this->imageMapper->find($this->userId, $face->getImage());
94
		if ($image === null) {
95
			return new JSONResponse([], Http::STATUS_NOT_FOUND);
96
		}
97
98
		$fileId = $image->getFile();
99
100
		$userFolder = $this->rootFolder->getUserFolder($this->userId);
101
		$nodes = $userFolder->getById($fileId);
102
		$file = $nodes[0];
103
104
		$ownerView = new \OC\Files\View('/'. $this->userId . '/files');
0 ignored issues
show
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...
105
		$path = $userFolder->getRelativePath($file->getPath());
106
107
		$img = new OCP_Image();
108
		$fileName = $ownerView->getLocalFile($path);
109
		$img->loadFromFile($fileName);
110
		$img->fixOrientation();
111
112
		$x = $face->getX();
113
		$y = $face->getY();
114
		$w = $face->getWidth();
115
		$h = $face->getHeight();
116
117
		$padding = $h*0.35;
118
		$x -= $padding;
119
		$y -= $padding;
120
		$w += $padding*2;
121
		$h += $padding*2;
122
123
		if ($this->settingsService->getObfuscateFaces()) {
124
			$this->hipsterize($img, $face);
125
		}
126
127
		$img->crop($x, $y, $w, $h);
128
		$img->scaleDownToFit($size, $size);
129
130
		$resp = new DataDisplayResponse($img->data(), Http::STATUS_OK, ['Content-Type' => $img->mimeType()]);
131
		$resp->setETag((string)crc32($img->data()));
132
		$resp->cacheFor(7 * 24 * 60 * 60);
133
		$resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT')));
134
135
		return $resp;
136
	}
137
138
	/**
139
	 * @NoAdminRequired
140
	 *
141
	 * @NoCSRFRequired
142
	 *
143
	 * @return DataDisplayResponse|JSONResponse
144
	 */
145
	public function getPersonThumb (string $name, int $size) {
146
		$modelId = $this->settingsService->getCurrentFaceModel();
147
		$personFace = current($this->faceMapper->findFromPerson($this->userId, $name, $modelId, 1));
148
		return $this->getThumb($personFace->getId(), $size);
149
	}
150
151
	/**
152
	 * @return void
153
	 */
154
	private function hipsterize(OCP_Image &$image, Entity &$face) {
155
		$imgResource = $image->resource();
156
157
		$landmarks = json_decode($face->getLandmarks(), true);
0 ignored issues
show
It seems like $face->getLandmarks() can also be of type null; however, parameter $json of json_decode() does only seem to accept string, 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

157
		$landmarks = json_decode(/** @scrutinizer ignore-type */ $face->getLandmarks(), true);
Loading history...
158
		if (count($landmarks) === 5) {
159
			$eyesX1 = $landmarks[2]['x'];
160
			$eyesY1 = $landmarks[2]['y'];
161
162
			$eyesX2 = $landmarks[0]['x'];
163
			$eyesY2 = $landmarks[0]['y'];
164
165
			$eyesXC = ($eyesX2 + $eyesX1)/2;
166
			$eyesYC = ($eyesY2 + $eyesY1)/2;
167
168
			$mustacheXC = $landmarks[4]['x'];
169
			$mustacheYC = $landmarks[4]['y'];
170
		}
171
		else if (count($landmarks) === 68) {
172
			$eyesX1 = $landmarks[36]['x'];
173
			$eyesY1 = $landmarks[36]['y'];
174
			$eyesX2 = $landmarks[45]['x'];
175
			$eyesY2 = $landmarks[45]['y'];
176
177
			$eyesXC = ($eyesX2 + $eyesX1)/2;
178
			$eyesYC = ($eyesY2 + $eyesY1)/2;
179
180
			$mustacheXC = $landmarks[52]['x'];
181
			$mustacheYC = $landmarks[52]['y'];
182
		}
183
		else {
184
			return;
185
		}
186
187
		$eyesW = $eyesX2 - $eyesX1;
188
		$eyesH = $eyesY2 - $eyesY1;
189
190
		$eyesL = sqrt(pow($eyesW, 2) + pow($eyesH, 2));
191
		$angle = rad2deg(atan(-$eyesH/$eyesW));
192
193
		$glassesGd = imagecreatefrompng(\OC_App::getAppPath('facerecognition') . '/img/glasses.png');
0 ignored issues
show
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...
194
		if ($glassesGd === false) return;
195
196
		$fillColor = imagecolorallocatealpha($glassesGd, 0, 0, 0, 127);
197
		$glassesGd = imagerotate($glassesGd, $angle, $fillColor);
198
		if ($glassesGd === false) return;
199
200
		$glassesW = imagesx($glassesGd);
201
		$glassesH = imagesy($glassesGd);
202
203
		$glassesRatio = $eyesL/$glassesW*1.5;
204
205
		$glassesDestX = intval($eyesXC - $glassesW * $glassesRatio / 2);
206
		$glassesDestY = intval($eyesYC - $glassesH * $glassesRatio / 2);
207
		$glassesDestW = intval($glassesW * $glassesRatio);
208
		$glassesDestH = intval($glassesH * $glassesRatio);
209
210
		imagecopyresized($imgResource, $glassesGd, $glassesDestX, $glassesDestY, 0, 0, $glassesDestW, $glassesDestH, $glassesW, $glassesH);
211
212
		$mustacheGd = imagecreatefrompng(\OC_App::getAppPath('facerecognition') . '/img/mustache.png');
213
		if ($mustacheGd === false) return;
214
215
		$fillColor = imagecolorallocatealpha($mustacheGd, 0, 0, 0, 127);
216
		$mustacheGd = imagerotate($mustacheGd, $angle, $fillColor);
217
		if ($mustacheGd === false) return;
218
219
		$mustacheW = imagesx($mustacheGd);
220
		$mustacheH = imagesy($mustacheGd);
221
222
		$mustacheRatio = $eyesL/$glassesW*1.1;
223
224
		$mustacheDestX = intval($mustacheXC - $mustacheW * $mustacheRatio / 2);
225
		$mustacheDestY = intval($mustacheYC - $mustacheH * $mustacheRatio / 2);
226
		$mustacheDestW = intval($mustacheW * $mustacheRatio);
227
		$mustacheDestH = intval($mustacheH * $mustacheRatio);
228
229
		imagecopyresized($imgResource, $mustacheGd, $mustacheDestX, $mustacheDestY, 0, 0, $mustacheDestW, $mustacheDestH, $mustacheW, $mustacheH);
230
231
		$image->setResource($imgResource);
232
	}
233
234
}
235