书法图片自动扣字的批处理

本程序会根据原文字图片,自动扣字并生成黑字、红字2个透明的png图片,原图片黑字或白字均可。运行的话需要先安装好 ImageMagick-7.1.1-37

用法与生成效果举例:

a.jpg 白字 转 黑、红扣字png:

b.jpg 黑字 转 黑、红扣字png:

分享脚本如下:

windows版:(花好几个小时写好的)

bash 复制代码
:: # 先安装好 ImageMagick-7.1.1-37

@echo off
setlocal EnableDelayedExpansion

:: 检查输入参数
if "%~1"=="" (
    echo 请输入输入文件名
    echo 用法: %0 input.jpg output
    exit /b 1
)

if "%~2"=="" (
    echo 请输入输出文件名前缀
    echo 用法: %0 input.jpg output
    exit /b 1
)

:: 定义输入和输出文件
set "input=%~1"
set "output_prefix=%~2"
set "tmp_jpg=%output_prefix%_binary.jpg"
set "black_output=%output_prefix%_b.png"
set "red_output=%output_prefix%_r.png"



:: 亮度与对比度调整
magick "%input%" -brightness-contrast 0x80 "%tmp_jpg%"
magick "%tmp_jpg%" -brightness-contrast 0x80 "%tmp_jpg%"

:: 转为灰度
:: magick "%tmp_jpg%" -colorspace Gray "%tmp_jpg%"

:: 去噪音操作
magick "%tmp_jpg%" -morphology Erode Octagon:1 -morphology Dilate Octagon:1 "%tmp_jpg%"

:: 二值化处理
magick "%tmp_jpg%" -threshold 50%% "%tmp_jpg%"



:: 获取图像的宽度和高度
for /f "tokens=1,2 delims=x" %%a in ('magick identify -format "%%wx%%h" "%tmp_jpg%"') do (
    set "width=%%a"
    set "height=%%b"
)

if "%width%"=="" (
    echo 无法获取图像的宽度和高度
    exit /b 1
)

echo Width = %width%, Height = %height%

:: 计算总像素数量
set /a total_pixels=%width% * %height%
if %total_pixels% LEQ 0 (
    echo 无效的像素总数
    exit /b 1
)

:: 计算白色像素数量
for /F "tokens=*" %%i in ('magick "%tmp_jpg%" -format "%%[fx:mean]" info:') do (
    set "mean_color=%%i"
)

:: 提取整数部分和小数部分
for /F "tokens=1,2 delims=." %%a in ("%mean_color%") do (
    set "int_part=%%a"
    set "dec_part=%%b"
)

:: 默认小数部分为0
if not defined dec_part set "dec_part=00"

:: 判断小数部分是否大于 50(即 0.50)
set "is_greater=0"
if "%int_part%" GEQ "1" (
    set "is_greater=1"
) else (
    if "%int_part%" EQU "0" (
        if "%dec_part:~0,2%" GEQ "50" (
            set "is_greater=1"
        )
    )
)

:: 输出结果
if %is_greater% EQU 1 (
    echo 白色占比 %mean_color% > 0.5,判断原图为黑字
) else (
	magick "%tmp_jpg%" -negate "%tmp_jpg%"
    echo 白色占比 %mean_color% ≤ 0.5,判断原图为白字,已作反转
)

:: 存黑字png
magick "%tmp_jpg%" -fuzz 5%% -fill none -opaque white "%black_output%"

:: 转回成rgb
magick "%tmp_jpg%" -type TrueColor "%tmp_jpg%"

:: 黑字转红色
magick "%tmp_jpg%" -fuzz 35%% -fill red -opaque black "%tmp_jpg%"

:: 存红字png
magick "%tmp_jpg%" -fuzz 5%% -fill none -opaque white "%red_output%"

:: 删除临时文件
del /q "%tmp_jpg%"

echo 处理完成,生成文件: %black_output% 和 %red_output%

endlocal

转linux版:(暂未测试)

bash 复制代码
#!/bin/bash

# 先安装好 ImageMagick-7.1.1-37


# 检查输入参数
if [ -z "$1" ] || [ -z "$2" ]; then
    echo "用法: $0 input.jpg output_prefix"
    exit 1
fi

input="$1"
output_prefix="$2"
tmp_jpg="${output_prefix}_binary.jpg"
black_output="${output_prefix}_b.png"
red_output="${output_prefix}_r.png"

# 亮度与对比度调整
magick "$input" -brightness-contrast 0x80 "$tmp_jpg"
magick "$tmp_jpg" -brightness-contrast 0x80 "$tmp_jpg"

# 去噪音操作
magick "$tmp_jpg" -morphology Erode Octagon:1 -morphology Dilate Octagon:1 "$tmp_jpg"

# 二值化处理
magick "$tmp_jpg" -threshold 50% "$tmp_jpg"

# 获取图像的宽度和高度
dimensions=$(magick identify -format "%wx%h" "$tmp_jpg")
width=$(echo "$dimensions" | cut -d'x' -f1)
height=$(echo "$dimensions" | cut -d'x' -f2)

if [ -z "$width" ] || [ -z "$height" ]; then
    echo "无法获取图像的宽度和高度"
    exit 1
fi

echo "Width = $width, Height = $height"

# 计算总像素数量
total_pixels=$((width * height))
if [ "$total_pixels" -le 0 ]; then
    echo "无效的像素总数"
    exit 1
fi

# 计算白色像素数量
mean_color=$(magick "$tmp_jpg" -format "%[fx:mean]" info:)
mean_color_int=${mean_color%.*}
mean_color_dec=${mean_color#*.}
mean_color_dec=${mean_color_dec:0:2}

# 判断小数部分是否大于 50(即 0.50)
if [ "$mean_color_int" -ge 1 ] || { [ "$mean_color_int" -eq 0 ] && [ "$mean_color_dec" -ge 50 ]; }; then
    echo "白色占比 $mean_color > 0.5, 判断原图为黑字"
else
    magick "$tmp_jpg" -negate "$tmp_jpg"
    echo "白色占比 $mean_color ≤ 0.5, 判断原图为白字,已作反转"
fi

# 存黑字png
magick "$tmp_jpg" -fuzz 5% -fill none -opaque white "$black_output"

# 转回成rgb
magick "$tmp_jpg" -type TrueColor "$tmp_jpg"

# 黑字转红色
magick "$tmp_jpg" -fuzz 35% -fill red -opaque black "$tmp_jpg"

# 存红字png
magick "$tmp_jpg" -fuzz 5% -fill none -opaque white "$red_output"

# 删除临时文件
rm -f "$tmp_jpg"

echo "处理完成,生成文件: $black_output 和 $red_output"

转PHP版

(先转一下编码,还有一些问题,貌似是我安装的Imagick版本的问题,有的方法不支持)

在 PHP 后端实现类似的图像处理功能,可以使用Imagick扩展来操作图像。Imagick 是 PHP 的一个扩展,用于处理图像,支持许多图像处理操作,如调整亮度、对比度、二值化等。

php 复制代码
<?php

// 检查输入参数
if ($argc < 3) {
    echo "用法: php script.php input.jpg output_prefix\n";
    exit(1);
}

$input = $argv[1];
$outputPrefix = $argv[2];
$tmpJpg = $outputPrefix . '_binary.jpg';
$blackOutput = $outputPrefix . '_b.png';
$redOutput = $outputPrefix . '_r.png';

try {
    // 创建 Imagick 对象
    $image = new Imagick($input);

    // 亮度与对比度调整
    $image->modulateImage(100, 100, 160); // 模拟亮度与对比度调整

    // 去噪音操作
    $image->morphologyImage(Imagick::MORPHOLOGY_ERODE, Imagick::MORPHOLOGY_OCTAGON, 1);
    $image->morphologyImage(Imagick::MORPHOLOGY_DILATE, Imagick::MORPHOLOGY_OCTAGON, 1);

    // 二值化处理
    $image->thresholdImage(0.5 * Imagick::getQuantum());

    // 获取图像的宽度和高度
    $width = $image->getImageWidth();
    $height = $image->getImageHeight();
    
    if ($width === false || $height === false) {
        echo "无法获取图像的宽度和高度\n";
        exit(1);
    }
    
    echo "Width = $width, Height = $height\n";

    // 计算图像的平均颜色值
    $image->normalizeImage();
    $meanColor = $image->getImageHistogram();

    $totalPixels = $width * $height;

    if ($totalPixels <= 0) {
        echo "无效的像素总数\n";
        exit(1);
    }

    // 获取平均颜色
    $meanColor = array_reduce($meanColor, function($carry, $pixel) {
        $carry['r'] += $pixel->getColorValue(Imagick::COLOR_RED);
        $carry['g'] += $pixel->getColorValue(Imagick::COLOR_GREEN);
        $carry['b'] += $pixel->getColorValue(Imagick::COLOR_BLUE);
        return $carry;
    }, ['r' => 0, 'g' => 0, 'b' => 0]);

    $meanColor['r'] /= count($meanColor);
    $meanColor['g'] /= count($meanColor);
    $meanColor['b'] /= count($meanColor);

    $meanValue = ($meanColor['r'] + $meanColor['g'] + $meanColor['b']) / 3;

    if ($meanValue > 0.5) {
        echo "平均颜色值大于0.5, 原图为白底黑字\n";
    } else {
        $image->negateImage();
        echo "平均颜色值小于或等于0.5, 原图为黑底白字, 已反转\n";
    }

    // 存黑字PNG
    $image->writeImage($blackOutput);

    // 转回成RGB
    $image->setImageType(Imagick::IMGTYPE_TRUECOLORMATTE);

    // 黑字转红色
    $image->colorizeImage(new ImagickPixel('red'), 1);
    $image->writeImage($redOutput);

    // 删除临时文件(如果有的话)

    echo "处理完成,生成文件: $blackOutput 和 $redOutput\n";

} catch (ImagickException $e) {
    echo 'Imagick 错误: ' . $e->getMessage() . "\n";
    exit(1);
}

?>

PHP中调用bat或sh

前面一直尝试用Imagick 扩展来操作图像,但可能是Imagick版本变化的关系,一直没有成功。改用调用bat或sh的方式实现。

php 复制代码
<?php
// 检查输入参数
if ($argc < 3) {
    echo "用法: php toPng.php input.jpg output_prefix\n";
    exit(1);
}

// 验证输入文件路径
$inputFile = escapeshellarg($argv[1]);
$outputPrefix = escapeshellarg($argv[2]);
$blackOutput = escapeshellarg($outputPrefix . '_b.png');
$redOutput = escapeshellarg($outputPrefix . '_r.png');

// 批处理文件的路径,确保这是正确的路径
$batFile = './toPng.bat'; // 如果在当前目录
// $batFile = 'C:/path/to/your/toPng.bat'; // 如果不在当前目录,使用绝对路径

// 不需要再次使用 escapeshellarg,因为我们已经验证了输入
$command = sprintf('"%s" "%s" "%s"', $batFile, $inputFile, $outputPrefix);

$descriptorspec = array(
    0 => array("pipe", "r"),  // stdin
    1 => array("pipe", "w"),  // stdout
    2 => array("pipe", "w")   // stderr
);

$process = proc_open($command, $descriptorspec, $pipes);

if (is_resource($process)) {
    // 关闭 stdin
    fclose($pipes[0]);

    // 读取 stdout
    $output = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    // 读取 stderr
    $error = stream_get_contents($pipes[2]);
    fclose($pipes[2]);

    // 关闭进程
    $returnVar = proc_close($process);

    // 检查执行结果
    if ($returnVar === 0) {
        echo "图像处理成功,生成文件: {$blackOutput} 和 {$redOutput}\n";
    } else {
        echo "图像处理失败,返回码: $returnVar\n";
        echo "错误输出:\n" . $error;
    }
} else {
    echo "无法打开进程\n";
}

?>
php 复制代码
<?php
// 检查输入参数
if ($argc < 3) {
    echo "用法: php script.php input_file output_prefix\n";
    exit(1);
}

// 验证输入文件路径
$inputFile = escapeshellarg($argv[1]);
$outputPrefix = escapeshellarg($argv[2]);
$blackOutput = escapeshellarg($outputPrefix . '_b.png');
$redOutput = escapeshellarg($outputPrefix . '_r.png');

// shell 脚本的路径
$shFile = escapeshellarg('./toPng.sh'); // 确保这是正确的路径

// 构造命令
$command = sprintf('sh %s %s %s', $shFile, $inputFile, $outputPrefix);

$descriptorspec = array(
    0 => array("pipe", "r"),  // stdin
    1 => array("pipe", "w"),  // stdout
    2 => array("pipe", "w")   // stderr
);

$process = proc_open($command, $descriptorspec, $pipes);

if (is_resource($process)) {
    // 关闭 stdin
    fclose($pipes[0]);

    // 读取 stdout
    $output = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    // 读取 stderr
    $error = stream_get_contents($pipes[2]);
    fclose($pipes[2]);

    // 关闭进程
    $returnVar = proc_close($process);

    // 检查执行结果
    if ($returnVar === 0) {
        echo "图像处理成功,生成文件: {$blackOutput} 和 {$redOutput}\n";
    } else {
        echo "图像处理失败,返回码: $returnVar\n";
        echo "错误输出:\n" . $error;
    }
} else {
    echo "无法打开进程\n";
}

?>
相关推荐
i嗑盐の小F9 小时前
【 ACM独立出版,见刊后1个月检索!!!】第二届通信网络与机器学习国际学术会议(CNML 2024,10月25-27)
网络·图像处理·人工智能·深度学习·算法·机器学习·计算机视觉
waf1391620 小时前
MFC中使用OpenCV动态绘制图像ROI区域(矩形+多边形)
c++·图像处理·mfc
知来者逆1 天前
智慧农业——InsectMamba利用状态空间模型对害虫进行分类
图像处理·人工智能·计算机视觉·数据挖掘·智慧农业
不是很强 但是很秃1 天前
秃姐学AI系列之:实战Kaggle比赛:狗的品种识别(ImageNet Dogs)
图像处理·人工智能·pytorch·深度学习·神经网络·计算机视觉·分类
RaidenQ1 天前
2024.9.13 Python与图像处理新国大EE5731课程大作业,SIFT 特征和描述符,单应性矩阵透视变换
图像处理·python·矩阵·sift
mirror_zAI1 天前
[OpenCV] 数字图像处理 C++ 学习——15像素重映射(cv::remap) 附完整代码
c++·图像处理·opencv·计算机视觉
爱奔跑的虎子1 天前
FPGA与Matlab图像处理之伽马校正
图像处理·matlab·fpga开发·fpga·vivado·xilinx
hola1738414391 天前
opencv之Canny边缘检测
图像处理·opencv·计算机视觉
视觉人机器视觉2 天前
更新20240915机器视觉海康Visionmaster学习步骤
图像处理·人工智能·深度学习·学习·计算机视觉
PlumCarefree2 天前
USB摄像头视频流转RTSP流
图像处理·ffmpeg·音视频·媒体·视频编解码