/**
  * Paving entry point
  * Используется для запуска механизма замащивания
  * @param int $accuracy
  * @param float|int $partOpacity
  * @return bool
  */
 public function paving($accuracy = 32, $partOpacity = 1)
 {
     if (count($this->segments) == 0) {
         echo "Segmentation map is empty!\n";
         return false;
     }
     if (!$this->partRepo) {
         echo "PartRepo is not defined!\n";
         return false;
     }
     $segmentsCount = count($this->segments);
     echo "Paving for " . $segmentsCount . " segments...\n";
     $counter = 1;
     foreach ($this->segments as $segment) {
         /** @var Segment $segment */
         $part = $this->partRepo->findOneWithColorLike($segment->getAvgColor(), $accuracy);
         if (!$part) {
             continue;
         }
         echo "Found image for {$segment} ({$counter} / {$segmentsCount})\n";
         $segment->setPart($part);
         $tile = new ImagickExt($this->webDir . $part->getPath());
         $tile->resizeImage($segment->getEndX() - $segment->getStartX(), $segment->getEndY() - $segment->getStartY(), \Imagick::FILTER_LANCZOS, 1);
         $tile->setImageOpacity($partOpacity);
         $this->imagick->compositeImage($tile, \Imagick::COMPOSITE_OVER, $segment->getStartX(), $segment->getStartY());
         $counter++;
     }
     return true;
 }
 /**
  * @param InputInterface $input
  * @param OutputInterface $output
  * @return int|null|void
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     // php app/console gfb:mosaic:create --file="4.jpg" --size=32 --level=2 --accuracy=16 --opacity=0.6
     $this->webDir = $this->getContainer()->get("kernel")->getRootDir() . "/../web/";
     $this->originsPath = $this->getContainer()->getParameter("gfb_mosaic.origins_dir");
     $this->resultsPath = $this->getContainer()->getParameter("gfb_mosaic.results_dir");
     $this->basePath = $this->getContainer()->getParameter("gfb_mosaic.base_dir");
     $this->output = $output;
     if (!extension_loaded('imagick')) {
         $output->writeln("Error: Imagick not found! You should install it!");
         return -1;
     }
     $mosaicFullPath = $this->webDir . $this->resultsPath;
     if (!file_exists($mosaicFullPath)) {
         mkdir($mosaicFullPath, 0777);
     }
     if (!is_writable($mosaicFullPath)) {
         chmod($mosaicFullPath, 0777);
     }
     $imagick = new ImagickExt();
     $needleFormats = array("JPG", "JPEG", "PNG", "GIF");
     $formatsAll = $imagick->queryFormats();
     if (count(array_intersect($needleFormats, $formatsAll)) != count($needleFormats)) {
         $output->writeln("Error: not all the required formats are supported!");
         exit;
     }
     $name = $input->getOption('file');
     $partSize = $input->getOption('size');
     $segmentationLevel = $input->getOption("level");
     $accuracy = $input->getOption('accuracy');
     $partOpacity = $input->getOption("opacity");
     $imagick->readImage($this->webDir . $this->originsPath . $name);
     // Do some magic!
     try {
         $processor = new MosaicProcessor($imagick, $this->webDir);
         $processor->setPartRepo($this->getContainer()->get("doctrine")->getEntityManager()->getRepository("GFBMosaicBundle:Part"));
         $processor->segmentation($partSize, $segmentationLevel);
         $processor->paving($accuracy, $partOpacity);
         $imagick->writeImage($mosaicFullPath . "R" . $name);
         $markupGen = new MarkupGenerator($this->webDir, $this->basePath);
         $markupGen->generate($imagick, $this->resultsPath . "R" . $name, $processor->getSegments());
     } catch (\Exception $ex) {
         echo $ex->getMessage() . "\n";
     }
     // Finish some magic!
     return 0;
 }
    /**
     * Run markup file generation
     * Запустить генерацию файла с версткой
     * @param ImagickExt $imagick
     * @param string $filePath
     * @param Segment[] $segments
     */
    public function generate($imagick, $filePath, $segments)
    {
        $markup = "\n<style>\n    .mosaic_canvas {\n        width: 960px;\n        margin: 0 auto;\n        background-image: url(/{$filePath});\n        background-size: 100% auto;\n        position: relative;\n    }\n\n    .mosaic_canvas img {\n        width: 100%;\n    }\n\n    .mosaic_part:hover {\n        background: rgba(95, 158, 160, 0.5);\n    }\n\n    .mosaic_popup {\n        margin-left: -210px;\n        width: 420px;\n        background: #808080;\n        padding: 24px;\n        display: none;\n        position: absolute;\n        left: 50%;\n        top: 25%;\n    }\n\n    .mosaic_popup img {\n        width: 100%;\n    }\n</style>\n        ";
        $markup .= "<div class=\"mosaic_canvas\">";
        $markup .= "    <img src='/{$filePath}' style='visibility:hidden;'/>";
        $cW = $imagick->getWidth();
        $cH = $imagick->getHeight();
        echo "\nCanvas size : {$cW}x{$cH}\n";
        foreach ($segments as $segment) {
            $markup .= $this->itemCode($cW, $cH, $segment);
        }
        $markup .= "</div>";
        $markup .= '
<div class="mosaic_popup">
    <img src="#"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
    if (window.jQuery != undefined) {
        $(function() {
            var $popup = $(".mosaic_popup");

            $(".mosaic_canvas .mosaic_part").click(function(event) {
                event.stopPropagation();
                $popup.find("img").attr("src", $(this).data("orig"));
                $popup.show();
            });

            $("body").click(function() {
                $popup.hide();
            });
        });
    }
</script>
';
        file_put_contents($this->webDir . $filePath . ".html", $markup);
    }
 /**
  * @param array $results
  * @param string $color
  */
 private function processResults($results, $color)
 {
     $em = $this->getEm();
     /** @var PartRepo $partRepo */
     $partRepo = $em->getRepository("GFBMosaicBundle:Part");
     foreach ($results as $imgData) {
         $code = md5($imgData["imageId"] . $imgData["url"]);
         $this->output->write("  >>> " . $imgData["url"]);
         $imagick = new ImagickExt();
         try {
             $imagick->readImage($imgData["url"]);
         } catch (\Exception $ex) {
             $this->output->writeln(" [FAIL] ");
             continue;
         }
         $this->output->writeln(" [OK] ");
         $imagick->cutToSquare();
         $imagick->setFormat("png");
         $filename = $code . ".png";
         $imagick->writeImage($this->webDir . $this->basePath . $filename);
         $part = $partRepo->findOneByCode($code);
         if (!$part) {
             $part = new Part();
         }
         $part->setAvgColor($imagick->getAvgColor())->setCode($code)->setPath($filename)->setWidth($imagick->getWidth())->setHeight($imagick->getHeight())->setColor($color);
         if ($part->getId() > 0) {
             $em->merge($part);
         } else {
             $em->persist($part);
         }
         $em->flush();
     }
 }