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

news2024/9/29 22:16:19

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

用法与生成效果举例:

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

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

分享脚本如下:

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

:: # 先安装好 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版:(暂未测试)

#!/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

// 检查输入参数
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
// 检查输入参数
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
// 检查输入参数
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";
}

?>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2087871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kafka 到数据仓库:使用 bend-ingest-kafka 将消息加载到 Databend

将消息从 Apache Kafka 导入到像 Databend 这样的云数据仓库可能是一项艰巨的任务。bend-ingest-kafka 工具简化了这一过程&#xff0c;使您能够轻松地将 Kafka 消息导入到 Databend 表中。 什么是 bend-ingest-kafka&#xff1f; bend-ingest-kafka 工具是一个专门为从 Apac…

网上一堆教人用AI做自媒体的,真的能挣钱吗?看我真实测评~

今日主题&#xff1a;AI副业能做吗&#xff1f; 今年这情况&#xff0c;几乎所有人都想搞个副业。 有人问我&#xff1a;普通人真的能靠AI做自媒体搞钱吗&#xff1f; 先说结论&#xff1a;可以&#xff0c;但要找准路子&#xff01; 听我慢慢道来~ 我是今年开始做AI自媒体…

同声传译用什么软件?5款优质软件评测

最近&#xff0c;我遇到了一个尴尬的情况。在一次国际会议中&#xff0c;我被分配到了一个多语言小组讨论。虽然我的英语还算流利&#xff0c;但面对来自世界各地的同事们&#xff0c;各种口音和语速让我感到有些力不从心。 那一刻&#xff0c;我多么希望有一个神奇的工具&…

如何解决已经安装软航文档控件但依旧提示未安装的问题

目录 前言 问题现象 问题处理步骤 前言 本文介绍在办公系统中使用重庆软航科技有限公司开发的NTKO OFFICE文档控件软件时&#xff0c;已经通过办公系统提供的软件安装包安装&#xff0c;但是在360安全浏览器、360极速浏览器的兼容模式下依旧提示&#xff1a;本机尚未安装跨浏…

STM32F411 标准库硬件SPI (硬件NSS/CS)驱动st7735--1.8寸TFT显示屏

TFT的spi驱动文件 完整工程网盘放在末尾 #include "lcd_driver.h"static uint16_t SPI_TIMEOUT_UserCallback(uint8_t errorCode);//液晶IO初始化配置 void LCD_Driver_Init(void) {SPI_InitTypeDef SPI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;/* 使能…

关于武汉芯景科技有限公司的实时时钟芯片XJ8340开发指南(兼容DS1340)

一、芯片引脚介绍 1.芯片引脚 2.引脚描述 二、系统结构图 三、功能描述 1.时钟功能 2.频率输出 / 普通IO口 FT/OUT引脚输出512HZ的方波或者高低电平 3.备用电源 4.涓流充电 5.振荡停止检测 四、程序代码 XJ8340.C /** XJ8340.c** Created on: 2024年8月29日* Auth…

萤石开放平台 播放报错4012,URL过期或无效

当你在尝试打开直播地址时&#xff0c;如果遇到了报错提示“4012&#xff0c;URL过期或无效&#xff0c;请检查URL的有效性”。 这通常表示直播地址中的UUID&#xff08;一个独特的识别码&#xff09;可能存在问题&#xff0c;例如过期或无权限访问。以下是一些排查及解决该问题…

【ACM独立出版 | 厦大主办】第五届计算机科学与管理科技国际学术会议(ICCSMT 2024,10月18-20)

第五届计算机科学与管理科技国际学术会议(ICCSMT 2024) 定于2024年10月18-20日在中国厦门举行。 会议旨在为从事“计算机科学”与“管理科技”研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术&#xff0c;了解学术发展趋势&#xff0c;拓宽研究思路…

Pandas 绘图的强大之处:后端

轻松通过 Pandas 创建交互式图形。欢迎来到雲闪世界。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 1.背景 Python 有大量的可视化包&#xff0c;其中最有名的三个是&#xff1a;Matplotlib&#xff08;和 seaborn&#xff09;、Plotly和Hvplot。这三…

虚幻5|技能栏UI优化(2)——优化技能UI并实现技能栏的拖拽操作

这篇文章里&#xff0c;前情提要&#xff0c;文章里的序列变量应命名为序号&#xff0c;我命名错了&#xff0c;虽然不差&#xff0c;但为了后面更好的理解 一.刷新技能栏&#xff0c;用于刷新上一章文章的初始化技能栏 1.打开技能栏格子&#xff0c;打开图表&#xff0c;添加…

用AI工具制作高质量PPT的完整教程

其实使用AI或者ChatGPT写PPT的方式有很多种 下面主要说明两种方式&#xff0c;建议第二种方式 接下来我会用最简单的语言&#xff0c;一步一步说明&#xff0c;保证你能在五分钟内做完你想要的PPT 具体方法和工具&#xff0c;都在里面 1、手动生成 让ChatGPT帮你生成大纲和…

Leetcode面试经典150题-36.有效数独

解法都在代码里&#xff0c;不懂就留言或者私信&#xff0c;比第一题稍微难点 class Solution {public static boolean isValidSudoku(char[][] board) {/**rowExists[i][j]代表第i行是否存在数据j1*/boolean[][] rowExists new boolean[9][9];/**rowExists[i][j]代表第i列是…

纵向合并单元格——table

将list数据处理成tableDate格式&#xff0c;id重复的数据&#xff0c;只有第一项有num字段&#xff08;num是重复的个数&#xff09;渲染表格&#xff0c;纵向合并第1、2、6列&#xff0c;id相同的合并 <template><div><el-table:data"tableData":sp…

力扣刷题--137. 只出现一次的数字 II【中等】

题目描述&#x1f357; 给你一个整数数组 nums &#xff0c;除某个元素仅出现 一次 外&#xff0c;其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。 示例 1&#xff1a; 输入&am…

knime一行代码都不用写,就可以清洗数据,详细文字

knime数据清洗案例 最终效果 解决办法&#xff1a; 图文并茂的解决办法见我公众号&#xff1a;链接: knime一行代码都不用写&#xff0c;就可以清洗数据,详细步骤如下 具体使用的节点说明如下&#xff1a; 1、使用Excel Reader结节&#xff0c;将数据导入进来。 2.使用…

科技馆可视化系统:全新互动体验

通过图扑科技馆可视化平台&#xff0c;参观者可以体验互动式展示和虚拟现实展览&#xff0c;深入理解科学现象和技术创新&#xff0c;增强学习的趣味性和参与感。

HarmonyOS(52) 使用安全控件SaveButton保存图片

SaveButton使用简介 前言SaveButton简介约束与限制 实现点击事件全部源码 参考资料&#xff1a; 前言 在HarmonyOS(50) 截图保存功能实现一文中简单介绍了截图保存功能&#xff0c;本篇博文介绍一个更简单的保存图片控件SaveButton. SaveButton简介 SaveButton允许用户通过点…

全球财经动态:科技巨头风云再起,市场趋势显分化

一、美股大盘与债市动向 昨夜美股市场呈现分化格局&#xff0c;中概股表现强劲&#xff0c;而科技龙头英伟达却遭遇重挫。道指微涨&#xff0c;纳指小幅收跌&#xff0c;标普500指数则基本持平。美债收益率攀升&#xff0c;十年期国债收益率触及3.863%&#xff0c;市场避险情绪…

JavaWeb学习——原理篇学习

一、SpringBoot配置优先级 首先我们先知道三种SpringBoot支持的配置文件: 而当在一个Spring项目中&#xff0c;如果同时存在这三个配置文件&#xff0c;那么执行的优先级顺序应是&#xff1a; properties > yml > yaml 。 补充&#xff1a;属性配置 另外我们可以通过打包…

把http网站变成https

网站建设好后默认是HTTP网站&#xff0c;会被浏览器直接标注为不安全站点&#xff0c;甚至搜索引擎上也排名也不是那么出色。 HTTP协议是浏览网站和在线资源的基本协议。由于HTTP的连接未加密&#xff0c;因此往往不安全。HTTPS是默认HTTP协议的安全扩展。 访问HTTPS网站时&…