update cmd handling, fix bugs

This commit is contained in:
Dennis Eichhorn 2022-03-05 16:58:59 +01:00
parent a86685a04d
commit 755ee54f0c
14 changed files with 137 additions and 145 deletions

View File

@ -15,6 +15,7 @@ declare(strict_types=1);
namespace phpOMS\Ai\Ocr\Tesseract;
use phpOMS\System\File\PathException;
use phpOMS\System\SystemUtils;
/**
* Tesseract api
@ -54,87 +55,6 @@ final class TesseractOcr
self::$bin = \realpath($path);
}
/**
* Run git command.
*
* @param string $cmd Command to run
*
* @return string[]
*
* @throws \Exception
*
* @since 1.0.0
*/
private function run(string $cmd) : array
{
if (\strtolower((string) \substr(\PHP_OS, 0, 3)) === 'win') {
$cmd = 'cd ' . \escapeshellarg(\dirname(self::$bin))
. ' && ' . \basename(self::$bin)
. ' '
. $cmd;
} else {
$cmd = \escapeshellarg(self::$bin)
. ' '
. $cmd;
}
$pipes = [];
$desc = [
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
];
$resource = \proc_open($cmd, $desc, $pipes, null, null);
if ($resource === false) {
throw new \Exception();
}
$stdout = \stream_get_contents($pipes[1]);
$stderr = \stream_get_contents($pipes[2]);
foreach ($pipes as $pipe) {
\fclose($pipe);
}
$status = \proc_close($resource);
if ($status == -1) {
throw new \Exception((string) $stderr);
}
return $this->parseLines(\trim($stdout === false ? '' : $stdout));
}
/**
* Parse lines.
*
* @param string $lines Result of git command
*
* @return string[]
*
* @since 1.0.0
*/
private function parseLines(string $lines) : array
{
$lineArray = \preg_split('/\r\n|\n|\r/', $lines);
$lines = [];
if ($lineArray === false) {
return $lines;
}
foreach ($lineArray as $line) {
$temp = \preg_replace('/\s+/', ' ', \trim($line, ' '));
if (!empty($temp)) {
$lines[] = $temp;
}
}
return $lines;
}
/**
* Prase image
*
@ -167,7 +87,8 @@ final class TesseractOcr
*/
public function parseImage(string $image, array $languages = ['eng'], int $psm = 3, int $oem = 3) : string
{
$this->run(
SystemUtils::runProc(
self::$bin,
$image . ' '
. ($temp = \tempnam(\sys_get_temp_dir(), 'ocr_'))
. ' --psm ' . $psm

View File

@ -65,7 +65,7 @@ final class Skew
$avg /= $start[1] - $end[1];
$dimImMatrix = [$end[0] - $start[0], $end[1] - $start[1]];
$dimImMatrix = [\count($imMatrix), \count($imMatrix[0])];
$bestScore = 0;
$bestDegree = 0;
@ -77,7 +77,7 @@ final class Skew
$rotated = self::rotatePixelMatrix($imMatrix, $dimImMatrix, $i);
$hist = [];
for ($j = 0; $j < $dimImMatrix[1]; ++$j) {
for ($j = 0; $j < $dimImMatrix[0]; ++$j) {
$hist[$j] = \array_sum($rotated[$j]);
// cleanup for score function
@ -95,8 +95,6 @@ final class Skew
$im = \imagerotate($im, $bestDegree, 1);
// https://stackoverflow.com/questions/29981083/rotating-a-bit-matrix
if (\strripos($outPath, 'png') !== false) {
\imagepng($im, $outPath);
} elseif (\strripos($outPath, 'jpg') !== false || \strripos($outPath, 'jpeg') !== false) {
@ -118,13 +116,13 @@ final class Skew
$rotated = [[]];
for ($i = 0; $i < $dim[0]; ++$i) {
$cY = $i - $dim[1] / 2.0; // center
$cY = $i - $dim[0] / 2.0; // center
for ($j = 0; $j < $dim[1]; ++$j) {
$cX = $j - $dim[0] / 2.0; // center
$cX = $j - $dim[1] / 2.0; // center
$x = $cos * $cX + $sin * $cY + $dim[0] / 2.0;
$y = -$sin * $cX + $cos * $cY + $dim[1] / 2.0;
$x = $cos * $cX + $sin * $cY + $dim[1] / 2.0;
$y = -$sin * $cX + $cos * $cY + $dim[0] / 2.0;
$rotated[$i][$j] = self::getNearestValue($pixel, $dim, $x, $y);
}
@ -135,11 +133,11 @@ final class Skew
private static function getNearestValue(array $pixel, array $dim, float $x, float $y) : int
{
$xLow = \min((int) $x, $dim[0] - 1);
$xHigh = \min((int) \ceil($x), $dim[0] - 1);
$xLow = \min((int) $x, $dim[1] - 1);
$xHigh = \min((int) \ceil($x), $dim[1] - 1);
$yLow = \min((int) $y, $dim[1] - 1);
$yHigh = \min((int) \ceil($y), $dim[1] - 1);
$yLow = \min((int) $y, $dim[0] - 1);
$yHigh = \min((int) \ceil($y), $dim[0] - 1);
$points = [
[$xLow, $yLow],

View File

@ -54,12 +54,8 @@ final class Thresholding
$out = \imagecreate($dim[0], $dim[1]);
$intImg = [[]];
$s = (int) $dim[0] / 96; // can be changed 8
$t = 30; // can be changed 15
for ($i = 0; $i < $dim[0]; ++$i) {
$sum = 0;
$sum = 0.0;
for ($j = 0; $j < $dim[1]; ++$j) {
$rgb = \imagecolorat($im, $i, $j);
@ -69,16 +65,19 @@ final class Thresholding
}
}
$s = (int) ($dim[0] / 96.0); // can be changed 8
$t = 30; // can be changed 15
$black = \imagecolorallocate($out, 0, 0, 0);
$white = \imagecolorallocate($out, 255, 255, 255);
for ($i = 0; $i < $dim[0]; ++$i) {
for ($j = 0; $j < $dim[1]; ++$j) {
$x1 = \max(1, (int) ($i - $s / 2));
$x2 = \min((int) ($i + $s / 2), $dim[0] - 1);
$x1 = \max(1, (int) ($i - $s / 2.0));
$x2 = \min((int) ($i + $s / 2.0), $dim[0] - 1);
$y1 = \max(1, (int) ($j - $s / 2));
$y2 = \min((int) ($j + $s / 2), $dim[1] - 1);
$y1 = \max(1, (int) ($j - $s / 2.0));
$y2 = \min((int) ($j + $s / 2.0), $dim[1] - 1);
$count = ($x2 - $x1) * ($y2 - $y1);
$sum = $intImg[$x2][$y2] - $intImg[$x2][$y1 - 1] - $intImg[$x1 - 1][$y2] + $intImg[$x1 - 1][$y1 - 1];
@ -86,7 +85,7 @@ final class Thresholding
$rgb = \imagecolorat($im, $i, $j);
$brightness = ImageUtils::lightness($rgb);
$color = $brightness * $count <= ($sum * (100 - $t) / 100) ? $black : $white;
$color = $brightness * $count <= ($sum * (100.0 - $t) / 100.0) ? $black : $white;
\imagesetpixel($out, $i, $j, $color);
}

View File

@ -76,12 +76,7 @@ final class HttpRequest extends RequestAbstract
{
$this->header = new HttpHeader();
$this->header->l11n = $l11n ?? new Localization();
if ($uri !== null) {
$this->uri = $uri;
}
$this->init();
$this->uri = $uri ?? new HttpUri('');
}
/**
@ -93,13 +88,11 @@ final class HttpRequest extends RequestAbstract
*
* @since 1.0.0
*/
private function init() : void
public function initRequest() : void
{
if (!isset($this->uri)) {
$this->initCurrentRequest();
$this->lock();
self::cleanupGlobals();
}
$this->initCurrentRequest();
$this->lock();
self::cleanupGlobals();
$this->data = \array_change_key_case($this->data, \CASE_LOWER);
}
@ -394,7 +387,10 @@ final class HttpRequest extends RequestAbstract
*/
public static function createFromSuperglobals() : self
{
return new self();
$request = new self();
$request->initRequest();
return $request;
}
/**

View File

@ -289,4 +289,9 @@ abstract class RequestAbstract implements MessageInterface
{
return $this->files;
}
public function addFile(array $file) : void
{
$this->files[] = $file;
}
}

View File

@ -13,6 +13,8 @@ With Karaka you have one partner who can provide all the tools and software solu
- [Installation](#installation)
- [Requirements](#requirements)
- [Setup](#setup)
- [End-User](#end-user)
- [Developer](#developer)
- [Philosophy](#philosophy)
- [Development Status](#development-status)
- [Features](#features)
@ -86,6 +88,7 @@ Features this framework provides are:
* Utils (e.g. barcodes, comporession, unit converter, jobqueue, git, etc.)
* Value validation
* View management
* Image processing
* Stdlib (e.g. graph, map, queue, enum, etc.)
## Unit Tests

View File

@ -146,4 +146,62 @@ final class SystemUtils
return 'localhost.localdomain';
}
public static function runProc(string $executable, string $cmd) : array
{
if (\strtolower((string) \substr(\PHP_OS, 0, 3)) === 'win') {
$cmd = 'cd ' . \escapeshellarg(\dirname($executable))
. ' && ' . \basename($executable)
. ' '
. $cmd;
} else {
$cmd = \escapeshellarg($executable)
. ' '
. $cmd;
}
$pipes = [];
$desc = [
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
];
$resource = \proc_open($cmd, $desc, $pipes, null, null);
if ($resource === false) {
throw new \Exception();
}
$stdout = \stream_get_contents($pipes[1]);
$stderr = \stream_get_contents($pipes[2]);
foreach ($pipes as $pipe) {
\fclose($pipe);
}
$status = \proc_close($resource);
if ($status == -1) {
throw new \Exception((string) $stderr);
}
$lines = \trim($stdout === false ? '' : $stdout);
$lineArray = \preg_split('/\r\n|\n|\r/', $lines);
$lines = [];
if ($lineArray === false) {
return $lines;
}
foreach ($lineArray as $line) {
$temp = \preg_replace('/\s+/', ' ', \trim($line, ' '));
if (!empty($temp)) {
$lines[] = $temp;
}
}
return $lines;
}
}

View File

@ -198,11 +198,13 @@ final class UriFactory
private static function unique(string $url) : string
{
// handle edge cases / normalization
/*
$url = \str_replace(
['=%', '=#', '=?'],
['=%25', '=%23', '=%3F'],
$url
);
*/
if (\stripos($url, '?') === false && ($pos = \stripos($url, '&')) !== false) {
$url = \substr_replace($url, '?', $pos, 1);

View File

@ -64,17 +64,17 @@ final class ImageUtils
public static function lightnessFromRgb(int $r, int $g, int $b) : float
{
$vR = $r / 255;
$vG = $g / 255;
$vB = $b / 255;
$vR = $r / 255.0;
$vG = $g / 255.0;
$vB = $b / 255.0;
$lR = $vR <= 0.04045 ? $vR / 12.92 : \pow((($vR + 0.055) / 1.055), 2.4);
$lG = $vG <= 0.04045 ? $vG / 12.92 : \pow((($vG + 0.055) / 1.055), 2.4);
$lB = $vB <= 0.04045 ? $vB / 12.92 : \pow((($vB + 0.055) / 1.055), 2.4);
$y = 0.2126 * $lR + 0.7152 * $lG + 0.0722 * $lB;
$lStar = $y <= 216 / 24389 ? $y * 24389 / 27 : \pow($y,(1 / 3)) * 116 - 16;
$lStar = $y <= 216.0 / 24389.0 ? $y * 24389.0 / 27.0 : \pow($y, (1 / 3)) * 116.0 - 16.0;
return $lStar / 100;
return $lStar / 100.0;
}
}

View File

@ -30,10 +30,11 @@ class Cron extends SchedulerAbstract
*/
public function create(TaskAbstract $task) : void
{
$this->run('-l > ' . __DIR__ . '/tmpcron.tmp');
\file_put_contents(__DIR__ . '/tmpcron.tmp', $task->__toString() . "\n", \FILE_APPEND);
$this->run(__DIR__ . '/tmpcron.tmp');
\unlink(__DIR__ . '/tmpcron.tmp');
$path = \tempnam(\sys_get_temp_dir(), 'cron_');
$this->run('-l > ' . $path);
\file_put_contents($path, $task->__toString() . "\n", \FILE_APPEND);
$this->run($path);
\unlink($path);
}
/**
@ -41,10 +42,11 @@ class Cron extends SchedulerAbstract
*/
public function update(TaskAbstract $task) : void
{
$this->run('-l > ' . __DIR__ . '/tmpcron.tmp');
$path = \tempnam(\sys_get_temp_dir(), 'cron_');
$this->run('-l > ' . $path);
$new = '';
$fp = \fopen(__DIR__ . '/tmpcron.tmp', 'r+');
$fp = \fopen($path, 'r+');
if ($fp) {
$line = \fgets($fp);
@ -59,11 +61,11 @@ class Cron extends SchedulerAbstract
}
\fclose($fp);
\file_put_contents(__DIR__ . '/tmpcron.tmp', $new);
\file_put_contents($path, $new);
}
$this->run(__DIR__ . '/tmpcron.tmp');
\unlink(__DIR__ . '/tmpcron.tmp');
$this->run($path);
\unlink($path);
}
/**
@ -79,10 +81,11 @@ class Cron extends SchedulerAbstract
*/
public function deleteByName(string $name) : void
{
$this->run('-l > ' . __DIR__ . '/tmpcron.tmp');
$path = \tempnam(\sys_get_temp_dir(), 'cron_');
$this->run('-l > ' . $path);
$new = '';
$fp = \fopen(__DIR__ . '/tmpcron.tmp', 'r+');
$fp = \fopen($path, 'r+');
if ($fp) {
$line = \fgets($fp);
@ -97,11 +100,11 @@ class Cron extends SchedulerAbstract
}
\fclose($fp);
\file_put_contents(__DIR__ . '/tmpcron.tmp', $new);
\file_put_contents($path, $new);
}
$this->run(__DIR__ . '/tmpcron.tmp');
\unlink(__DIR__ . '/tmpcron.tmp');
$this->run($path);
\unlink($path);
}
/**
@ -109,10 +112,11 @@ class Cron extends SchedulerAbstract
*/
public function getAll() : array
{
$this->run('-l > ' . __DIR__ . '/tmpcron.tmp');
$path = \tempnam(\sys_get_temp_dir(), 'cron_');
$this->run('-l > ' . $path);
$jobs = [];
$fp = \fopen(__DIR__ . '/tmpcron.tmp', 'r+');
$fp = \fopen($path, 'r+');
if ($fp) {
$line = \fgets($fp);
@ -136,8 +140,8 @@ class Cron extends SchedulerAbstract
\fclose($fp);
}
$this->run(__DIR__ . '/tmpcron.tmp');
\unlink(__DIR__ . '/tmpcron.tmp');
$this->run($path);
\unlink($path);
return $jobs;
}
@ -147,10 +151,11 @@ class Cron extends SchedulerAbstract
*/
public function getAllByName(string $name, bool $exact = true) : array
{
$this->run('-l > ' . __DIR__ . '/tmpcron.tmp');
$path = \tempnam(\sys_get_temp_dir(), 'cron_');
$this->run('-l > ' . $path);
$jobs = [];
$fp = \fopen(__DIR__ . '/tmpcron.tmp', 'r+');
$fp = \fopen($path, 'r+');
if ($fp) {
$line = \fgets($fp);
@ -168,8 +173,8 @@ class Cron extends SchedulerAbstract
\fclose($fp);
}
$this->run(__DIR__ . '/tmpcron.tmp');
\unlink(__DIR__ . '/tmpcron.tmp');
$this->run($path);
\unlink($path);
return $jobs;
}

View File

@ -355,4 +355,9 @@ class View extends ViewAbstract
{
return $this->l11nManager->getDateTime($this->l11n, $datetime, $format);
}
public function renderUserName(string $format, array $names) : string
{
return \trim(\preg_replace('/\s+/', ' ', \sprintf($format, ...$names)));;
}
}

View File

@ -37,4 +37,4 @@ final class SkewTest extends \PHPUnit\Framework\TestCase
[1700, 900]
);
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 144 KiB