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

本程序会根据原文字图片,自动扣字并生成黑字、红字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 outputexit /b 1
)if "%~2"=="" (echo 请输入输出文件名前缀echo 用法: %0 input.jpg outputexit /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" ]; thenecho "用法: $0 input.jpg output_prefix"exit 1
fiinput="$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" ]; thenecho "无法获取图像的宽度和高度"exit 1
fiecho "Width = $width, Height = $height"# 计算总像素数量
total_pixels=$((width * height))
if [ "$total_pixels" -le 0 ]; thenecho "无效的像素总数"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 ]; }; thenecho "白色占比 $mean_color > 0.5, 判断原图为黑字"
elsemagick "$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"),  // stdin1 => array("pipe", "w"),  // stdout2 => array("pipe", "w")   // stderr
);$process = proc_open($command, $descriptorspec, $pipes);if (is_resource($process)) {// 关闭 stdinfclose($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"),  // stdin1 => array("pipe", "w"),  // stdout2 => array("pipe", "w")   // stderr
);$process = proc_open($command, $descriptorspec, $pipes);if (is_resource($process)) {// 关闭 stdinfclose($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.rhkb.cn/news/414792.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring MVC 八股文

目录 重点 SpringMVC的工作原理 Spring MVC 拦截器 Spring MVC 的拦截器和 Filter 过滤器有什么差别&#xff1f; 基础 什么是SpringMVC SpringMVC的优点 Spring MVC的核心组件 Spring MVC的常用注解由有哪些 Controller 注解有什么用 重点 SpringMVC的工作原理 1、客…

OLED显示屏详解(IIC协议0.96寸 STM32)

目录 一、介绍 二、模块原理 1.原理图 2.工作原理&#xff1a;SSD1306显存与命令 三、程序设计 main.c文件 oled.h文件 oled.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 OLED是有机发光二极管&#xff0c;又称为有机电激光显示&#xff08;Organic Electrol…

U-Mail垃圾邮件网关:一站式邮件安全防护方案

在当今的数字化时代&#xff0c;电子邮件已成为企业日常运营中不可或缺的通讯工具。然而&#xff0c;随着电子邮件的广泛应用&#xff0c;垃圾邮件也日益成为困扰企业的一大难题。如何有效防止垃圾邮件入侵&#xff0c;确保企业邮件系统的安全稳定运行&#xff0c;已成为众多企…

Python进阶08-爬虫

零、文章目录 Python进阶08-爬虫 1、爬虫介绍 &#xff08;1&#xff09;爬虫是什么 **网络爬虫:**又被称为网页蜘蛛&#xff0c;网络机器人&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取网络信息的程序或者脚本&#xff0c;另外一些不常使用的名字还有蚂蚁、自…

挂载磁盘时有多个文件系统

mount: /opt/storage/data1/: more filesystems detected on /dev/md5; use -t or wipefs(8). 1、解决方法一 mount -t ext4 /dev/md5 /opt/data2、解决方法二 #返回磁盘有那些文件系统和格式 wipefs /dev/md5 #清除文件系统和元数据 wipefs -a -f /dev/md5 #再次查看将没有任…

算法导论 总结索引 | 第五部分 第二十三章:最小生成树

需要将多个组件的针脚 连接在一起。要连接n个针脚&#xff0c;可以使用 n-1 根连线&#xff0c;每根连线连接两个针脚。很显然&#xff0c;希望所使用的连线长度最短 用一个连通无向图 G (V, E) 来予以表示&#xff0c;这里的 V 是针脚的集合&#xff0c;E 是针脚之间的可能连…

华为网络工程师证书等级有哪些?怎么备考?

华为网络工程师是由华为技术厂商推出的一系列网络工程师认证&#xff0c;其主要目的就是为了培养了验证网络工程师在华为技术以及解决方案方面的拥有一定的专业知识及技能&#xff0c;该证书分为多个等级&#xff0c;涵盖了不同网络领域及技术&#xff0c;也为众多的网络工程师…

spring security 自定义图形验证码(web/前后端分离)

一、准备工作 1.1 导入pom 所需依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.3</version><!-- <version>2.7.18</version>-->&l…

微信小程序知识点(一)

1.条件判断&#xff1a; wx:if&#xff0c;wx:elif&#xff0c;wx:else 和Hidden的区别 wx:if等是动态实现组件的&#xff0c;符合条件&#xff0c;页面上就新增一个组件&#xff0c;不符合&#xff0c;就会在也页面上加载&#xff0c;而Hidden只是控制页面的组件的显示与否&…

CUDA 计算点集与点集之间的距离

文章目录 一、简介二、实现代码三、实现效果参考资料 一、简介 这里使用CUDA实现一种计算计算点集与点集之间的距离的方法&#xff0c;其思路很简单&#xff0c;就是计算每个点到另一个点集之间的最小距离&#xff0c;最终保存结果到一个数组中&#xff0c;通过这种方式可以快速…

海力士A-DIE颗粒内存条震撼发布:毁灭者星际战舰DDR5内存条登场

**海力士A-DIE颗粒内存条震撼发布&#xff1a;毁灭者星际战舰内存条登场** 近日&#xff0c;海力士正式发布了全新一代A-DIE颗粒内存条——毁灭者星际战舰DDR5 7200RGB电竞内存条。这款内存条凭借其卓越的性能和先进的技术&#xff0c;成为数码爱好者关注的焦点。 导语&#xf…

分类预测|基于麻雀优化核极限学习机的数据分类预测Matlab程序SSA-KELM 多特征输入多类别输出 含基础KELM

分类预测|基于麻雀优化核极限学习机的数据分类预测Matlab程序SSA-KELM 多特征输入多类别输出 含基础KELM 文章目录 前言分类预测|基于麻雀优化核极限学习机的数据分类预测Matlab程序SSA-KELM 多特征输入多类别输出 含基础KELM 一、SSA-KELM模型SSA-KELM 分类预测的详细原理和流…

剑侠情缘c#版(游戏源码+资源+工具+程序),百度云盘下载,大小1.68G

剑侠情缘c#版&#xff08;游戏源码资源工具程序&#xff09;&#xff0c;c#开发的&#xff0c;喜欢研究游戏的可以下载看看。亲测可进游戏。 剑侠情缘c#版&#xff08;游戏源码资源工具程序&#xff09;下载地址&#xff1a; 通过网盘分享的文件&#xff1a;【游戏】剑侠情缘c#…

U-Mail垃圾邮件过滤网关‍是如何过滤垃圾邮件的?

随着互联网的普及&#xff0c;垃圾邮件已经成为计算机网络安全的又一个公害。因此&#xff0c;反垃圾邮件已经成为互联网应用研究中一个重要课题。为了防止垃圾邮件首先要学会保护自己的邮件地址&#xff0c;避免在网上随意登记和使用邮件地址&#xff0c;预防垃圾邮件骚扰。其…

Mysql——高可用集群部署

目录 一、源码编译mysql 二、mysql的主从复制 2.1、主从复制 2.2、延迟复制 2.3、慢查询日志 2.4、MySQL的并行复制 三、MySQL半同步模式 四、mysql高可用组复制 五、mysql-router 六、mysql高可用MHA 七、为MHA添加VIP功能 一、源码编译mysql 1、安装依赖 [rootm…

Pyqt5高级技巧:多线程任务、窗体交互、常用控件介绍(含基础Demo)

目录 一、多线程任务和多窗体交互 二、增删改查Demo 三、UI设计 【css效果代码对照表】 【实现效果】 【实现代码】 【常见问题】 Q1&#xff1a;工具栏怎么加&#xff0c;资源图片怎么加 Q2&#xff1a;控件被背景染色怎么办&#xff1f; Q3&#xff1a;QTdesigner有…

磐石云语音识别引擎

磐石云发布了V1.2.2版本语音识别引擎。 经过严格客观的测试识别效果和阿里云、讯飞、火山进行了对比几乎无差。&#xff08;欢迎对比测试&#xff09; 上图是CPU下的流式识别效果 RTF0.1~0.14,也就是一并发一个小时大约处理7~10小时&#xff0c;这取决于硬件的配置&#xff0…

MathType常见问题汇总

文章目录 MathType常见问题汇总一、如何将MathType内嵌到WPS工具栏中&#xff1f;二、在word中&#xff0c;如何批量修改所有MathType公式的字体以及大小格式&#xff1f;三、如何解决插入MathType公式后的行间距发生改变&#xff1f;参考 MathType常见问题汇总 一、如何将Mat…

Altium designer设计经验谈——常用规则的使用(二)

文章目录 前言三、规则设置介绍——走线规则1、Routing——>Width 线宽2、Routing——>Topology 拓扑 四、规则设置介绍——平面层规则1、Plane——>电源层连接样式 Power Plane Connect Style2、Plane——>电源层间距距离 Power Plane Clearance3、Plane——>多…

Oracle rac模式下undo表空间爆满的解决

文章目录 前言一、确认对应实例的undo表空间二、确认对应实例undo的文件位置三、确认回滚段使用情况四、检查undo segment状态五、创建新的undo表空间并进行切换六、等待原undo表空间segment状态变更为offline七、删除原undo表空间以及数据文件 前言 一、确认对应实例的undo表空…