public function onUpload(Form $form)
 {
     /** @var UploadControl[] $form */
     /** @var FileUpload $json */
     /** @var FileUpload $audio */
     $json = $form['json']->getValue();
     $audio = $form['audio']->getValue();
     $data = Json::decode($json->getContents(), Json::FORCE_ARRAY);
     $blackboard = new Rme\Blackboard();
     $this->orm->contents->attach($blackboard);
     $blackboard->title = 'Nová nahrávka';
     $blackboard->description = ' ';
     $blackboard->hidden = TRUE;
     $blackboard->duration = $data['duration'];
     $blackboard->preview = 'https://placehold.it/480x320&text=...';
     $blackboard->author = $this->userEntity;
     $this->orm->flush();
     $base = $this->paths->getBlackboards() . "/{$blackboard->id}";
     $json->move("{$base}.json");
     $audio->move("{$base}.wav");
     $producer = $this->queue->getProducer('blackboardPreview');
     $producer->publish(serialize(['blackboard' => new EntityPointer($blackboard)]));
     $link = $this->link('BlackboardEditor:default', ['blackboardId' => $blackboard->id]);
     $this->sendJson(['redirect' => $link]);
 }
 public function generate(Blackboard $bb, $outfile)
 {
     $raw = file_get_contents($this->paths->getBlackboards() . "/{$bb->id}.json");
     $data = Json::decode($raw, Json::FORCE_ARRAY);
     $min = ['width' => PHP_INT_MAX, 'height' => PHP_INT_MAX];
     $max = ['width' => 0, 'height' => 0];
     foreach ($data['data'] as $row) {
         if ($row['type'] !== 'beginStroke' && $row['type'] !== 'strokeTo') {
             continue;
         }
         $min['width'] = min($min['width'], $row['loc']['x']);
         $min['height'] = min($min['height'], $row['loc']['y']);
         $max['width'] = max($max['width'], $row['loc']['x']);
         $max['height'] = max($max['height'], $row['loc']['y']);
     }
     $margin = 20;
     $min['width'] -= $margin;
     $min['height'] -= $margin;
     $max['width'] += $margin;
     $max['height'] += $margin;
     $ratio = 2;
     $canvas = imagecreatetruecolor(($max['width'] - $min['width']) * $ratio, ($max['height'] - $min['height']) * $ratio);
     if (function_exists('imageantialias')) {
         // this function is not in php5-gd and requires recompiling php
         imageantialias($canvas, TRUE);
     }
     $last = NULL;
     foreach ($data['data'] as $row) {
         if ($row['type'] === 'beginStroke') {
             $last = $row['loc'];
         } else {
             if ($row['type'] === 'strokeTo') {
                 $c = $row['color'];
                 $color = imagecolorallocate($canvas, $c['r'], $c['g'], $c['b']);
                 $this->imagelinethick($canvas, ($last['x'] - $min['width']) * $ratio, ($last['y'] - $min['height']) * $ratio, ($row['loc']['x'] - $min['width']) * $ratio, ($row['loc']['y'] - $min['height']) * $ratio, $color, 3);
                 $last = $row['loc'];
             } else {
                 if ($row['type'] === 'erase') {
                     $color = imagecolorallocate($canvas, 0, 0, 0);
                     $radius = 11 * $ratio;
                     $x = ($row['loc']['x'] - $min['width']) * $ratio;
                     $y = ($row['loc']['y'] - $min['height']) * $ratio;
                     imagefilledarc($canvas, $x, $y, $radius, $radius, 0, 360, $color, IMG_ARC_PIE);
                 }
             }
         }
     }
     imagepng($canvas, $outfile, 9);
 }