<?php
/**
* SeekQuarry/Yioop --
* Open Source Pure PHP Search Engine, Crawler, and Indexer
*
* Copyright (C) 2009 - 2026 Chris Pollett chris@pollett.org
*
* LICENSE:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* END LICENSE
*
* @author Chris Pollett chris@pollett.org
* @license https://www.gnu.org/licenses/ GPL3
* @link https://www.seekquarry.com/
* @copyright 2009 - 2026
* @filesource
*/
namespace seekquarry\yioop\tests;
use seekquarry\yioop\configs as C;
use seekquarry\yioop\library\ComputerVision;
use seekquarry\yioop\library\UnitTest;
use seekquarry\yioop\library\processors\ImageProcessor;
use seekquarry\yioop\library\processors\PageProcessor;
/**
* ComputerVisionTest checks the quick judgment ComputerVision makes of
* whether a picture likely holds text, before tesseract is run on it.
*/
class ComputerVisionTest extends UnitTest
{
/**
* setUp has nothing to make; the case makes its own pictures.
*/
public function setUp()
{
}
/**
* tearDown has nothing to remove.
*/
public function tearDown()
{
}
/**
* printIsKeptAndShadingIsSkippedTestCase writes two pictures 400
* points square. One has lines of black letters on white, as a page
* has; it likely holds text. The other runs smoothly through every
* shade with grain over it, as a photograph does; it likely holds none,
* so tesseract is not run on it.
*/
public function printIsKeptAndShadingIsSkippedTestCase()
{
$side = 400;
$page = imagecreatetruecolor($side, $side);
imagefill($page, 0, 0, imagecolorallocate($page, 255, 255, 255));
$ink = imagecolorallocate($page, 0, 0, 0);
for ($line = 10; $line < $side - 20; $line += 20) {
imagestring($page, 5, 10, $line,
"Deliberation de l'Assemblea di Corsica", $ink);
}
$photo = imagecreatetruecolor($side, $side);
mt_srand(1);
for ($down = 0; $down < $side; $down++) {
for ($across = 0; $across < $side; $across++) {
$shade = min(255, intdiv(($across + $down) * 255,
2 * $side) + mt_rand(0, 40));
imagesetpixel($photo, $across, $down,
($shade << 16) | ($shade << 8) | $shade);
}
}
$judged = [];
foreach (["page" => $page, "photo" => $photo] as $name => $image) {
$path = C\TEST_DIR . "/test_files/vision_test_$name.png";
imagepng($image, $path);
$judged[$name] = ComputerVision::likelyHoldsText($path);
unlink($path);
}
$this->assertTrue($judged["page"], "lines of letters likely hold text");
$this->assertTrue(!$judged["photo"],
"smooth shading with grain likely holds none");
}
/**
* temporaryFilesGoToTheFetchersFolderTestCase checks that once
* PageProcessor::$temp_dir names a fetcher's own folder, as each
* Fetcher sets it at start, the picture a processor saves to read its
* text goes there and not in the folder all processes share.
*/
public function temporaryFilesGoToTheFetchersFolderTestCase()
{
$own_folder = C\TEST_DIR . "/test_files/test-0-Fetcher";
if (!is_dir($own_folder)) {
mkdir($own_folder, 0777, true);
}
$shared_folder = PageProcessor::$temp_dir;
PageProcessor::$temp_dir = $own_folder;
$processor = new ImageProcessor();
$temp_file = $processor->saveTempFile("picture bytes",
"https://www.example.com/a.png", "png");
PageProcessor::$temp_dir = $shared_folder;
$this->assertEqual(dirname($temp_file), $own_folder,
"the processor wrote in the fetcher's own folder");
@unlink($temp_file);
@rmdir($own_folder);
}
/**
* scaledPictureForRecognitionTestCase checks that a picture wider than
* OCR_MOST_SIDE is written scaled down so its longer side is that
* many points, keeping its shape, and that a smaller picture is left
* as it is, giving no copy.
*/
public function scaledPictureForRecognitionTestCase()
{
$folder = C\TEST_DIR . "/test_files/";
$wide_path = $folder . "ocr_wide_test.png";
$small_path = $folder . "ocr_small_test.png";
imagepng(imagecreatetruecolor(1800, 900), $wide_path);
imagepng(imagecreatetruecolor(800, 600), $small_path);
$scaled_path = ComputerVision::scaledForRecognition($wide_path,
$folder);
$size = ($scaled_path === "") ? [0, 0] : getimagesize($scaled_path);
$this->assertEqual([$size[0], $size[1]],
[ComputerVision::OCR_MOST_SIDE, ComputerVision::OCR_MOST_SIDE / 2],
"the wide picture is scaled to the most side, keeping its shape");
$this->assertEqual(ComputerVision::scaledForRecognition($small_path,
$folder), "", "a small picture gets no scaled copy");
foreach ([$wide_path, $small_path, $scaled_path] as $path) {
if ($path !== "") {
@unlink($path);
}
}
}
}