Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 78 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
| ImageUtils | |
0.00% |
0 / 78 |
|
0.00% |
0 / 5 |
1190 | |
0.00% |
0 / 1 |
| olzImage | |
0.00% |
0 / 36 |
|
0.00% |
0 / 1 |
110 | |||
| getThumbSize | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
| generateThumbnails | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
20 | |||
| getThumbFile | |
0.00% |
0 / 32 |
|
0.00% |
0 / 1 |
272 | |||
| fromEnv | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace Olz\Utils; |
| 4 | |
| 5 | class ImageUtils { |
| 6 | use WithUtilsTrait; |
| 7 | |
| 8 | public const TABLES_IMG_DIRS = [ |
| 9 | 'karten' => 'img/karten/', |
| 10 | 'news' => 'img/news/', |
| 11 | 'questions' => 'img/questions/', |
| 12 | 'roles' => 'img/roles/', |
| 13 | 'snippets' => 'img/snippets/', |
| 14 | 'termine' => 'img/termine/', |
| 15 | 'termin_labels' => 'img/termin_labels/', |
| 16 | 'termin_locations' => 'img/termin_locations/', |
| 17 | 'termin_templates' => 'img/termin_templates/', |
| 18 | 'users' => 'img/users/', |
| 19 | 'weekly_picture' => 'img/weekly_picture/', |
| 20 | ]; |
| 21 | |
| 22 | public function olzImage( |
| 23 | string $db_table, |
| 24 | int|string|null $id, |
| 25 | ?string $index, |
| 26 | int $dim, |
| 27 | ?string $lightview = 'image', |
| 28 | string $attrs = '', |
| 29 | ): string { |
| 30 | $data_href = $this->envUtils()->getDataHref(); |
| 31 | $data_path = $this->envUtils()->getDataPath(); |
| 32 | if (!isset($this::TABLES_IMG_DIRS[$db_table])) { |
| 33 | $message = "Ungültige db_table: {$db_table} (in olzImage)"; |
| 34 | $this->log()->error($message); |
| 35 | return "<span style='color:#ff0000; font-style:italic;'>{$message}</span>"; |
| 36 | } |
| 37 | $db_imgpath = $this::TABLES_IMG_DIRS[$db_table]; |
| 38 | $imgfile = "{$db_imgpath}{$id}/img/{$index}"; |
| 39 | if (!$id || !$index || !is_file("{$data_path}{$imgfile}")) { |
| 40 | $message = "Bild nicht vorhanden (in olzImage): {$imgfile}"; |
| 41 | $this->log()->error($message); |
| 42 | return "<span style='color:#ff0000; font-style:italic;'>{$message}</span>"; |
| 43 | } |
| 44 | $info = getimagesize("{$data_path}{$imgfile}"); |
| 45 | $swid = $info[0] ?? 0; |
| 46 | $shei = $info[1] ?? 0; |
| 47 | if ($shei < $swid) { |
| 48 | $wid = $dim; |
| 49 | $hei = intval($wid * $shei / $swid); |
| 50 | } else { |
| 51 | $hei = $dim; |
| 52 | $wid = intval($hei * $swid / $shei); |
| 53 | } |
| 54 | $span_before = $lightview === 'image' ? "<span class='lightgallery'>" : ""; |
| 55 | $span_after = $lightview === 'image' ? "</span>" : ""; |
| 56 | $a_before = $lightview ? "<a href='{$data_href}{$imgfile}' aria-label='Bild vergrössern' data-src='{$data_href}{$imgfile}' onclick='event.stopPropagation()'>" : ""; |
| 57 | $a_after = $lightview ? "</a>" : ""; |
| 58 | |
| 59 | $url_without_dim = "{$data_href}img/{$db_table}/{$id}/thumb/{$index}"; |
| 60 | $thumbdim = $this->getThumbSize($dim); |
| 61 | $thumbdim2x = $thumbdim * 2; |
| 62 | return <<<ZZZZZZZZZZ |
| 63 | {$span_before}{$a_before} |
| 64 | <img |
| 65 | src='{$url_without_dim}\${$thumbdim}.jpg' |
| 66 | srcset='{$url_without_dim}\${$thumbdim2x}.jpg 2x, {$url_without_dim}\${$thumbdim}.jpg 1x' |
| 67 | alt='' |
| 68 | width='{$wid}' |
| 69 | height='{$hei}' |
| 70 | {$attrs} |
| 71 | /> |
| 72 | {$a_after}{$span_after} |
| 73 | ZZZZZZZZZZ; |
| 74 | } |
| 75 | |
| 76 | public function getThumbSize(int $size): int { |
| 77 | $ndim = $size - 1; |
| 78 | for ($i = 1; $i < 9 && ($ndim >> $i) > 0; $i++) { |
| 79 | } |
| 80 | return 1 << $i; |
| 81 | } |
| 82 | |
| 83 | /** @param array<string> $image_ids */ |
| 84 | public function generateThumbnails(array $image_ids, string $entity_img_path): void { |
| 85 | foreach ($image_ids as $image_id) { |
| 86 | for ($i = 5; $i < 9; $i++) { |
| 87 | $size = (1 << $i); |
| 88 | if (!is_file("{$entity_img_path}thumb/{$image_id}\${$size}.jpg")) { |
| 89 | $this->log()->info("Generate {$entity_img_path}thumb/{$image_id}\${$size}.jpg..."); |
| 90 | $this->getThumbFile($image_id, $entity_img_path, $size); |
| 91 | } |
| 92 | } |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | public function getThumbFile(string $image_id, string $entity_img_path, int $size): string { |
| 97 | if ($size !== 32 && $size !== 64 && $size !== 128 && $size !== 256 && $size !== 512) { |
| 98 | throw new \Exception("Size must be a power of two (32,64,128,256,512), was: {$size}"); |
| 99 | } |
| 100 | $imgfile = "{$entity_img_path}img/{$image_id}"; |
| 101 | $info = getimagesize($imgfile); |
| 102 | $swid = $info[0] ?? 0; |
| 103 | $shei = $info[1] ?? 0; |
| 104 | if ($shei < $swid) { |
| 105 | $wid = $size; |
| 106 | $hei = intval($wid * $shei / $swid); |
| 107 | } else { |
| 108 | $hei = $size; |
| 109 | $wid = intval($hei * $swid / $shei); |
| 110 | } |
| 111 | if ($wid <= 0 || $hei <= 0 || $wid > 800 || $hei > 800) { |
| 112 | $message = "getThumbFile: Invalid dimension: {$size}"; |
| 113 | $this->log()->warning($message); |
| 114 | throw new \Exception($message); |
| 115 | } |
| 116 | if ($wid > 256 || $hei > 256) { |
| 117 | $thumbfile = $imgfile; |
| 118 | } else { |
| 119 | $thumbfile = "{$entity_img_path}thumb/{$image_id}\${$size}.jpg"; |
| 120 | } |
| 121 | if (!is_file($thumbfile)) { |
| 122 | if (!is_dir(dirname($thumbfile))) { |
| 123 | mkdir(dirname($thumbfile), 0o777, true); |
| 124 | } |
| 125 | $img = imagecreatefromjpeg($imgfile); |
| 126 | if (!$img) { |
| 127 | $message = "getThumbFile: Could not open image {$imgfile}"; |
| 128 | $this->log()->warning($message); |
| 129 | throw new \Exception($message); |
| 130 | } |
| 131 | $thumb = imagecreatetruecolor($wid, $hei); |
| 132 | imagesavealpha($thumb, true); |
| 133 | imagecopyresampled($thumb, $img, 0, 0, 0, 0, $wid, $hei, $swid, $shei); |
| 134 | imagejpeg($thumb, $thumbfile, 90); |
| 135 | imagedestroy($thumb); |
| 136 | } |
| 137 | return $thumbfile; |
| 138 | } |
| 139 | |
| 140 | public static function fromEnv(): self { |
| 141 | return new self(); |
| 142 | } |
| 143 | } |