205 lines
6.2 KiB
PHP
205 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers;
|
|
|
|
use App\Controllers\BaseController;
|
|
use App\Models\webfax\FaxModel;
|
|
use App\Libraries\Qrcode;
|
|
use CodeIgniter\CLI\CLI;
|
|
use CodeIgniter\Exceptions\PageNotFoundException;
|
|
|
|
class Crontab extends BaseController
|
|
{
|
|
/**
|
|
* Fax 수신 이미지(tiff)를 jpg로 변경하고 Thumbnail을 만드는 작업...
|
|
* (CLI 전용)
|
|
*/
|
|
public function convertedFaxImages()
|
|
{
|
|
// ✅ CLI 전용 보호
|
|
if (!is_cli()) {
|
|
throw new PageNotFoundException();
|
|
}
|
|
|
|
/** @var FaxModel $faxModel */
|
|
$faxModel = model(FaxModel::class);
|
|
$qrCode = new Qrcode();
|
|
|
|
$res = $faxModel->selectFaxListNotExistsThumb();
|
|
$fileCnt = 0;
|
|
$receiver = 'uds_tiff';
|
|
|
|
if (empty($res)) {
|
|
CLI::write('No target fax images.', 'yellow');
|
|
return;
|
|
}
|
|
|
|
foreach ($res as $row) {
|
|
$fileCnt++;
|
|
CLI::write("\n\n[{$fileCnt}] Processing...", 'green');
|
|
|
|
$mid = $row['mid'] ?? null;
|
|
$file_name = $row['file_name'] ?? '';
|
|
$save_path = $row['save_path'] ?? '';
|
|
$caller_no = $row['caller_no'] ?? '';
|
|
$callee_no = $row['callee_no'] ?? '';
|
|
$tiff_file_name = $row['file_name'] ?? '';
|
|
$tiff_file_size = $row['file_size'] ?? '';
|
|
$recv_time = $row['recv_time'] ?? '';
|
|
$save_time = $row['save_time'] ?? '';
|
|
|
|
if (empty($save_path) || empty($file_name)) {
|
|
CLI::write(' - skip: save_path or file_name empty', 'yellow');
|
|
continue;
|
|
}
|
|
|
|
// ✅ pathinfo로 안전하게 처리
|
|
$ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
|
|
$base = pathinfo($file_name, PATHINFO_FILENAME);
|
|
|
|
if (!in_array($ext, ['tif', 'tiff'], true)) {
|
|
CLI::write(" - skip: not tif/tiff ({$ext})", 'yellow');
|
|
continue;
|
|
}
|
|
|
|
if (substr($save_path, -1) !== '/') {
|
|
$save_path .= '/';
|
|
}
|
|
|
|
$tiffPath = $save_path . $file_name;
|
|
if (!is_file($tiffPath)) {
|
|
CLI::write(" - skip: file not found ({$tiffPath})", 'yellow');
|
|
continue;
|
|
}
|
|
|
|
CLI::write(" - TIFF: {$tiffPath}");
|
|
|
|
try {
|
|
// ✅ TIFF 다중 페이지 안전 처리
|
|
$im = new \Imagick();
|
|
$im->readImage($tiffPath);
|
|
|
|
// coalesce: 멀티프레임 안정화(특히 tiff/gif 계열)
|
|
$frames = $im->coalesceImages();
|
|
|
|
$index = 0;
|
|
foreach ($frames as $frame) {
|
|
try {
|
|
// 페이지별 정보
|
|
$image_width = (int) $frame->getImageWidth();
|
|
$image_height = (int) $frame->getImageHeight();
|
|
$image_size = (int) $frame->getImageLength();
|
|
|
|
// 출력 경로
|
|
$jpgName = "{$base}_{$index}.jpg";
|
|
$jpgPath = $save_path . $jpgName;
|
|
$thumbName = "{$base}_{$index}_thumb.jpg";
|
|
$thumbPath = $save_path . $thumbName;
|
|
|
|
// ✅ JPG로 변환(페이지별로 frame clone 사용 권장)
|
|
$page = clone $frame;
|
|
|
|
// 이미지 포맷/품질(필요시 조정)
|
|
$page->setImageFormat('jpeg');
|
|
$page->setImageCompression(\Imagick::COMPRESSION_JPEG);
|
|
$page->setImageCompressionQuality(85);
|
|
|
|
// ✅ 리사이즈 (가로 800 제한)
|
|
if ($image_width > 800) {
|
|
$resize_width = 800;
|
|
$ratio = $resize_width / max(1, $image_width);
|
|
$resize_height = (int) round($image_height * $ratio);
|
|
$page->resizeImage($resize_width, $resize_height, \Imagick::FILTER_LANCZOS, 1, true);
|
|
}
|
|
|
|
if (!$page->writeImage($jpgPath)) {
|
|
CLI::write(" - fail: write jpg ({$jpgPath})", 'red');
|
|
$page->clear();
|
|
$page->destroy();
|
|
$index++;
|
|
continue;
|
|
}
|
|
|
|
// ✅ QR scan (실패해도 계속)
|
|
$qrcode_data = '';
|
|
try {
|
|
$qrcode_data = (string) $qrCode->scan($jpgPath);
|
|
} catch (\Throwable $e) {
|
|
log_message('error', 'QR scan failed: ' . $e->getMessage());
|
|
}
|
|
|
|
// ✅ 썸네일은 clone으로 (원본/페이지 훼손 방지)
|
|
$thumb = clone $page;
|
|
$thumb->thumbnailImage(105, 80, true);
|
|
|
|
if (!$thumb->writeImage($thumbPath)) {
|
|
CLI::write(" - fail: write thumb ({$thumbPath})", 'red');
|
|
// 그래도 JPG는 만들어졌으니 다음 진행은 정책에 따라 선택
|
|
}
|
|
|
|
CLI::write(" - JPG: {$jpgPath}");
|
|
CLI::write(" - THUMB: {$thumbPath}");
|
|
|
|
// ✅ DB 저장 (기존 시그니처 유지)
|
|
$faxModel->insertFaxImgs(
|
|
$mid,
|
|
$jpgName,
|
|
$save_path,
|
|
$thumbName,
|
|
$image_width,
|
|
$image_height,
|
|
$image_size,
|
|
$qrcode_data,
|
|
$caller_no,
|
|
$callee_no,
|
|
$tiff_file_name,
|
|
$tiffPath,
|
|
$tiff_file_size,
|
|
$recv_time,
|
|
$save_time,
|
|
$receiver
|
|
);
|
|
|
|
// ✅ 권한 처리 (에러 숨기지 말고 로그)
|
|
if (!@chmod($jpgPath, 0666)) {
|
|
log_message('error', "chmod failed: {$jpgPath}");
|
|
}
|
|
if (!@chmod($thumbPath, 0666)) {
|
|
log_message('error', "chmod failed: {$thumbPath}");
|
|
}
|
|
|
|
log_message('debug', $jpgPath);
|
|
log_message('debug', $thumbPath);
|
|
|
|
// ✅ 메모리 정리(프레임 단위)
|
|
$thumb->clear();
|
|
$thumb->destroy();
|
|
$page->clear();
|
|
$page->destroy();
|
|
} catch (\Throwable $e) {
|
|
log_message('error', 'Frame 처리 실패: ' . $e->getMessage());
|
|
}
|
|
|
|
// 다음 페이지
|
|
$index++;
|
|
}
|
|
|
|
// ✅ 전체 메모리 정리
|
|
$frames->clear();
|
|
$frames->destroy();
|
|
|
|
$im->clear();
|
|
$im->destroy();
|
|
|
|
gc_collect_cycles();
|
|
|
|
CLI::write(" - done.\n", 'green');
|
|
} catch (\Throwable $e) {
|
|
// 기존 writeLog 사용 중이면 그걸로 교체 가능
|
|
log_message('error', 'TIFF 처리 실패: ' . $e->getMessage());
|
|
CLI::write(" - error: " . $e->getMessage(), 'red');
|
|
}
|
|
}
|
|
}
|
|
}
|