commands as $path) { /** @var \swf2ass\DrawPath $path */ $line = new \swf2ass\ass\ASSLine(); $line->objectId = 0; $line->layer = [$frame[0]]; $line->start = $frame[1]; $line->end = $endFrame; $line->style = "f"; $line->name = $frame[3]; $shape = $path->commands; $line->tags = [ new \swf2ass\ass\borderTag(new \swf2ass\Vector2(0, 0)), new \swf2ass\ass\shadowTag(0), \swf2ass\ass\fillColorTag::fromStyleRecord($path->style) ]; /*if($shape->getRecords()[0] instanceof \swf2ass\MoveRecord){ $shape = (new \swf2ass\MatrixTransform(null, null, $shape->getRecords()[0]->to->multiply(-1)))->applyToShape($shape); }*/ $line->tags[] = new \swf2ass\ass\positionTag(new \swf2ass\Vector2(0, 0), new \swf2ass\Vector2(0, 0), 1, 1); $line->tags[] = new \swf2ass\ass\drawTag($shape, 1); echo $line->encode($frameDurationMs) . PHP_EOL; } } $fps = 30;//30000 / 1001;//30; $colorN = 2; $pframeColorDistance = 16; if (is_dir($argv[1])) { $frames = glob($argv[1] . "/*.png"); } else { $frames = [$argv[1]]; } sort($frames); /** @var \swf2ass\Color[][] $frameBuffer */ $frameBuffer = null; $quantizedFrameBuffer = $frameBuffer; $dynamicPalette = false; $palette = []; for ($i = 0; $i < $colorN; ++$i) { $palette[] = new \swf2ass\Color((int)round($i * (255 / ($colorN - 1))), (int)round($i * (255 / ($colorN - 1))), (int)round($i * (255 / ($colorN - 1)))); } $frameNumber = 1; $endFrame = 6522; $lastFrameNumber = null; $currentFrames = []; /** * @param \swf2ass\Color $color * @param \swf2ass\Color[] $palette * * @return \swf2ass\Color */ function getClosestColor(\swf2ass\Color $color, array $palette) { $minColor = null; $minDistance = null; foreach ($palette as $c2) { if (($d = $c2->distance($color)) < $minDistance or $minColor === null) { $minColor = $c2; $minDistance = $d; } } return $minColor; } foreach ($frames as $frame) { if (count($frames) === 1 or preg_match("/([0-9]+)\\.png/", $frame, $matches) > 0) { if (count($frames) === 1) { $frameNumber = 0; } else { $frameNumber = ((int)ltrim($matches[1], "0")); if ($frameNumber > $endFrame) { $endFrame = $frameNumber; } } $im = new Imagick(); $im->readImage($frame); $im->transformImageColorspace(Imagick::COLORSPACE_SRGB); $resolution = $im->getImageGeometry(); $resX = $resolution["width"]; $resY = $resolution["height"]; $iframe = []; $quantizedIframe = []; $pframe = []; $quantizedPframe = []; for ($y = 0; $y < $resY; ++$y) { $iframe[$y] = []; $quantizedIframe[$y] = []; $pframe[$y] = []; $quantizedPframe[$y] = []; for ($x = 0; $x < $resX; ++$x) { $pixel = $im->getImagePixelColor($x, $y); $c = $pixel->getColor(2); $color = new \swf2ass\Color($c["r"], $c["g"], $c["b"], $c["a"] ?? 255); $iframe[$y][$x] = $color; if ($frameBuffer !== null and $frameBuffer[$y][$x]->distance($color) > $pframeColorDistance) { $pframe[$y][$x] = $color; $frameBuffer[$y][$x] = $pframe[$y][$x]; } } } if ($dynamicPalette) { $im->quantizeImage($colorN, Imagick::COLORSPACE_SRGB, 0, false, true); } foreach ($iframe as $y => $row) { foreach ($row as $x => $color) { $pixel = $im->getImagePixelColor($x, $y); $c = $pixel->getColor(2); $color = new \swf2ass\Color($c["r"], $c["g"], $c["b"], $c["a"] ?? 255); if (!$dynamicPalette) { $color = getClosestColor($color, $palette); } $quantizedIframe[$y][$x] = $color; if (isset($pframe[$y][$x]) and $quantizedFrameBuffer[$y][$x]->distance($color) > $pframeColorDistance) { $quantizedPframe[$y][$x] = $color; $quantizedFrameBuffer[$y][$x] = $color; } } } if ($lastFrameNumber === null) { $headerFps = $fps * 2; echo <<render(false); $pframePathCount = array_reduce($pframeRender->commands, function (int $item, \swf2ass\DrawPath $path){ return $item + count($path->commands->getRecords()); }, 0); if ($frameBuffer === null or $pframePathCount > 0) { $iframeRender = (new \swf2ass\BitmapConverter($quantizedIframe))->render(true); $iframePathCount = array_reduce($iframeRender->commands, function (int $item, \swf2ass\DrawPath $path){ return $item + count($path->commands->getRecords()); }, 0); } if ($frameBuffer === null or ($pframePathCount > 0 and $iframePathCount <= $pframePathCount)) { fwrite(STDERR, " | IS IFRAME $frameNumber |$iframePathCount|$pframePathCount\n"); $frameBuffer = $iframe; $quantizedFrameBuffer = $quantizedIframe; foreach ($currentFrames as $f) { outputFrame($f, $frameNumber, (1 / $fps) * 1000); } $currentFrames = []; $currentFrames[] = [$frameNumber, $frameNumber, $iframeRender, "i"]; } else if ($pframePathCount > 0) { fwrite(STDERR, " | IS PFRAME $frameNumber |$iframePathCount|$pframePathCount\n"); $currentFrames[] = [$frameNumber, $frameNumber, $pframeRender, "p"]; } else { fwrite(STDERR, " | IS DROP $frameNumber |$iframePathCount|$pframePathCount\n"); } $lastFrameNumber = $frameNumber; } } foreach ($currentFrames as $f) { outputFrame($f, $endFrame, (1 / $fps) * 1000); }