NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

<?php
require_once(__DIR__ . '/require.php');

// 一時ファイルの削除
exec("find {$TMP} -type f | grep -v 'FAX.pdf' | xargs rm");

// 実行環境判定フラグ
// 0:コマンド実行 1:テスト実行 2:本番実行 3:本番訂正実行
$runFlg = posix_isatty(STDIN) ? 0 : 1;

// ここから、受信メールの添付PDFを取得
if ($runFlg == 1) {
require_once('Mail/mimeDecode.php');
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$params['input'] = file_get_contents('php://stdin');
$params['crlf'] = 'rn';
$mailList = Mail_mimeDecode::decode($params);

if (contains($mailList->headers['from'], '[email protected]')) {
$runFlg = 2;
} else if ($mailList->headers['subject'] == 'retry') {
$runFlg = 3;
}

foreach ($mailList->parts as $part) {
if (strtolower($part->ctype_primary) == 'application') {
file_put_contents("{$TMP}/FAX.pdf", $part->body);
break;
}
}
}

// PDFを画像に変換
exec("pdftoppm -jpeg {$TMP}/FAX.pdf {$TMP}/FAX");

// FAXページ数
$pageCount = count(glob("{$TMP}/FAX-*.jpg"));

// 10枚以上あるかどうか
$d = $pageCount >= 10 ? "%02d" : "%d";

// 上下逆さの判定
$isUpsideDown = isUpsideDown(sprintf("{$TMP}/FAX-{$d}.jpg", 1));

// ここから、画像のトリミング
define('W', 355); // トリミングの幅
define('H', 170); // トリミングの高さ
define('L', 150); // FAX左の余白
define('T', 470); // FAX上の余白

$dst_image = imagecreatetruecolor(W, H);
$cno = 1;

for ($i = 1; $i <= $pageCount; $i++) {
$path = sprintf("{$TMP}/FAX-{$d}.jpg", $i);

if ($isUpsideDown) {
exec("convert -rotate 180 {$path} {$path}");
}

for ($x = L + W * 2; $x >= L; $x -= W) {
for ($y = T + H * 6; $y >= T; $y -= H) {
if ($x == L && $y == T) {
continue;
}

imagecopyresampled($dst_image, imagecreatefromjpeg($path), 0, 0, $x, $y, W, H, W, H);
imagejpeg($dst_image, sprintf("{$TMP}/%03d.jpg", $cno));
$cno++;
}
}
}

function getCno($x, $y) {
// 余白を切り詰める
$x -= L; $y -= T;

// 範囲外
if ($x < 0 || $x >= W * 3 || $y < 0 || $y >= H * 7) { return -1; }

// 縦一列に並べる
while ($x >= W) {
$y += H * 7;
$x -= W;
}

// 上端の空セル分を切り詰める
$y -= H;

// 空セル
if ($y < 0) { return -1; }

return 20 - intdiv($y, H);
}

// ここから、OCRした文字列を配列にまとめる
$mismatch = [];
$client = new GoogleCloudVisionV1ImageAnnotatorClient();

for ($i = 1; $i <= $pageCount; $i++) {
$path = sprintf("{$TMP}/FAX-{$d}.jpg", $i);

foreach ($client->textDetection(file_get_contents($path))->getTextAnnotations() as $ta) {
$v = $ta->getBoundingPoly()->getVertices()->offsetGet(0);
$cno = getCno($v->getX(), $v->getY());
if ($cno == -1) {
continue;
}
$cno = sprintf('%03d', $cno + ($i - 1) * 20);
if (empty($mismatch[$cno])) {
$mismatch[$cno] = '';
}
$mismatch[$cno] .= $ta->getDescription();
}
}

ksort($mismatch);

// ここから、不要データを削除&誤読を置換
$arrStr = [];
$arrBlank = [];

foreach ($mismatch as $cno => &$str) {

// 空欄を削除
$fs = filesize("{$TMP}/{$cno}.jpg");
$ss = strlen(preg_replace('/[A-Z|]/', '', $str));
if ($ss < 8 || $fs < 8000) {
$arrBlank[$cno]['str'] = $mismatch[$cno];
$arrBlank[$cno]['strsize'] = $ss;
$arrBlank[$cno]['filesize'] = $fs;
unset($mismatch[$cno]);
continue;
}

$arrStr[$cno]['cno'] = sprintf('%d (p%d-%d)', $cno, ($cno - 1) / 20 + 1, ($cno - 1) % 20 + 1);
$arrStr[$cno]['前'] = $str;

// よくある誤読を置換
foreach (Typo::makeTypos() as $t) {
$str = preg_replace("/{$t->search}/u", $t->replace, $str);
}

// 台車Noを削除
$str = preg_replace('/N(o|O)D{0,2}[0-9B]{5,6}/', '〓', $str);
if (!contains($str, '〓')) {
$str = preg_replace('/(台|車)D{0,5}[0-9B]{5,6}/', '〓', $str);
}

$arrStr[$cno]['後'] = $str;
}

unset($str);

file_put_contents("{$TMP}/arrBlank.ser", serialize($arrBlank));
$cntAll = count($mismatch);

// NGページの有無を判定
$hasNgPage = $cntAll < ($pageCount - 1) * 20 + 1;

// ここから、店舗との突き合わせ
$tenpos = Tenpo::makeTenpos();

for ($i = 1; count($mismatch) > 0; $i++) {
foreach ($mismatch as $cno => $str) {
$matched = false;
foreach ($tenpos as $no => $t) {

if (($matched = match($i, $str, $no, $t)) === -1) {
break 3;
}

if ($matched) {
$t->countUp();
unset($mismatch[$cno]);
$t->res .= "{$cno} "; // check.php用
$arrStr[$cno]['p'] = $i;
break;
}
}
}
}

$cntNg = count($mismatch);

// 集計結果を保存(検証用)
file_put_contents("{$TMP}/tenpos.ser", serialize($tenpos));

// arrStrを保存
foreach ($mismatch as $cno => $v) {
$arrStr[$cno]['p'] = 'ng';
}
file_put_contents("{$TMP}/arrStr.ser", serialize($arrStr));

// ここから、集計メール本文を作成
define('LNS', 27); // メール本文の行数

$lines = array_fill(0, LNS + 4, '  ');
$lines[0] .= sprintf('%s(%s) 集計結果', date('n/j'), getDW(date('w')));
$lines[1] .= '合計: %d枚';
$lines[2] .= '(読取りOK=%d NG=%d)';

$i = 0;
foreach ($tenpos as $no => $t) {
$name = $t->name;
if (mb_strlen($name) == 2) {
$name .= ' ';
}
$lines[$i % LNS + 4] .= "{$no} {$name} {$t->cnt}" . ($t->cnt == 0 ? '!   ' : '    ');
$i++;
}

$text = implode("n", $lines);
$text = str_replace(['城山H', '千葉M'], ['城山H', '千葉M'], $text);
$text = sprintf($text, $cntAll, $cntAll - $cntNg, $cntNg);
$text .= "nn店舗情報の修正はこちら→ https://geji62jp.xyz/?cert=9758n";
if ($hasNgPage) {
$text = "n〓〓 紙ズレを検知しました  〓〓n〓〓 再度スキャンして下さい 〓〓nn" . $text;
}

// ここから、NG画像を集計メール添付用PDFに変換
if ($cntNg > 0) {
$base_image = imagecreate(1241, 1755);
imagecolorallocate($base_image, 255, 255, 255);

$border_image = imagecreate(W + 4, H + 4);
imagecolorallocate($border_image, 0, 0, 0);

$top = 100; // 上の余白
$m = 35; // マージン(xy共通)

$x = 55; // 左の余白
$y = $top;

foreach ($mismatch as $cno => $v) {
$src_image = imagecreatefromjpeg("{$TMP}/{$cno}.jpg");
imagecopyresampled($border_image, $src_image, 2, 2, 0, 0, W, H, W, H);
imagecopyresampled($base_image, $border_image, $x, $y, 0, 0, W + 4, H + 4, W + 4, H + 4);

$y += H + $m;

// 次の列へ
if ($y == $top + (H + $m) * 7) {
$y = $top;
$x += W + $m;
}
}

$path = sprintf("{$TMP}/NG_%s", date('Ymd'));
imagejpeg($base_image, "{$path}.jpg");
exec("convert {$path}.jpg {$path}.pdf");
}

// ここから、集計メールを送信
$file = $cntNg > 0 ? "{$path}.pdf" : null;

// 0:コマンド実行 1:テスト実行 2:本番実行 3:本番訂正実行
switch ($runFlg) {
case 0:
echo $text;
break;
case 1:
send('[email protected]', 'PCシール集計結果(テスト)', $text, $file);
break;
case 2:
send('[email protected],[email protected]', 'PCシール集計結果', $text, $file);

// 連続稼働日数を記録
$last_stopped = new DateTime('2023-07-24');
file_put_contents(__DIR__ . '/連続稼働日数', str_repeat('*', $last_stopped->diff(new DateTime())->format('%a')));
break;
case 3:
send('[email protected],[email protected]', 'PCシール集計結果(訂正版)', $text, $file);
break;
}

// 上下逆さを判定
function isUpsideDown($path) {
$arr = [];
$client = new GoogleCloudVisionV1ImageAnnotatorClient();
foreach ($client->textDetection(file_get_contents($path))->getTextAnnotations() as $ea) {
$arr[] = $ea->getBoundingPoly()->getVertices()->offsetGet(0)->getX();
}

for ($i = 0; $i < count($arr) - 1; $i++) {
$arr[$i] = ($arr[$i + 1] - $arr[$i] > 0) ? 1 : -1;
}
array_pop($arr);

return array_sum($arr) < 0;
}
     
 
what is notes.io
 

Notes.io is a web-based application for taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000 notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 12 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.