php 去除图片黑边,C#_c#扫描图片去黑边(扫描仪去黑边),自动去除图像扫描黑边复制代 - phpStudy...

///

/// 自动去除图像扫描黑边

///

///

public static void AutoCutBlackEdge(string fileName)

{

//打开图像

Bitmap bmp = OpenImage(fileName);

RemoveBlackEdge(bmp);

//保存图像

SaveImage(bmp, fileName);

}

private static byte[] rgbValues; // 目标数组内存

///

/// 图像去黑边

///

///

///

private static Bitmap RemoveBlackEdge(Bitmap bmp)

{

Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);

// 获取图像参数

int w = bmpData.Width;

int h = bmpData.Height;

int stride = bmpData.Stride;  // 扫描线的宽度

double picByteSize = GetPicByteSize(bmp.PixelFormat);

int bWidth = (int)Math.Ceiling(picByteSize * w); //显示宽度

int offset = stride - bWidth;  // 显示宽度与扫描线宽度的间隙

IntPtr ptr = bmpData.Scan0;   // 获取bmpData的内存起始位置

int scanBytes = stride * h;  // 用stride宽度,表示这是内存区域的大小

// 分别设置两个位置指针,指向源数组和目标数组

int posScan = 0;

rgbValues = new byte[scanBytes];  // 为目标数组分配内存

Marshal.Copy(ptr, rgbValues, 0, scanBytes);  // 将图像数据拷贝到rgbValues中

bool isPass = true;

int i = 0, j = 0;

int cutW = (int)(bWidth * 0.02); //2%宽度(可修改)

int cutH = (int)(h * 0.02);      //2%高度(可修改)

int posLen = (int)(picByteSize * 8); //继续查找深度为8的倍数(可修改)

//左边

for (i = 0; i < h; i++)

{

for (j = 0; j < bWidth; j++)

{

isPass = true;

if (rgbValues[posScan] < 255) rgbValues[posScan] = 255;

if (rgbValues[posScan + 1] == 255)

{

for (int m = 1; m <= posLen; m++)

{

if (rgbValues[posScan + m] < 255) isPass = false;

}

}

if (rgbValues[posScan + 1] < 255 || bWidth / 2 < j) isPass = false;

recCheck(ref rgbValues, posScan, h, stride, true);

posScan++;

if (j >= cutW && isPass) break;

}

// 跳过图像数据每行未用空间的字节,length = stride - width * bytePerPixel

if (j == bWidth) posScan += offset;

else posScan += (offset + bWidth - j - 1);

}

//右边

posScan = scanBytes - 1;

for (i = h - 1; i >= 0; i--)

{

posScan -= offset;

for (j = bWidth - 1; j >= 0; j--)

{

isPass = true;

if (rgbValues[posScan] < 255) rgbValues[posScan] = 255;

if (rgbValues[posScan - 1] == 255)

{

for (int m = 1; m <= posLen; m++)

{

if (rgbValues[posScan - m] < 255) isPass = false;

}

}

if (rgbValues[posScan - 1] < 255 || bWidth / 2 > j) isPass = false;

recCheck(ref rgbValues, posScan, h, stride, false);

posScan--;

if (cutH < (h - i))

if (j < (bWidth - cutW) && isPass) break;

}

// 跳过图像数据每行未用空间的字节,length = stride - width * bytePerPixel

if (j != -1) posScan -= j;

}

// 内存解锁

Marshal.Copy(rgbValues, 0, ptr, scanBytes);

bmp.UnlockBits(bmpData);  // 解锁内存区域

return bmp;

}

///

/// 上下去除黑边时,临近黑点去除

///

///

///

///

///

///

private static void recCheck(ref byte[] rgbValues, int posScan, int h, int stride, bool islLeft)

{

int scanBytes = h * stride;

int cutH = (int)(h * 0.01); //临近最大1%高度(可修改)

for (int i = 1; i <= cutH; i++)

{

int befRow = 0;

if (islLeft && (posScan - stride * i) > 0)

{

befRow = posScan - stride * i;

}

else if (!islLeft && (posScan + stride * i) < scanBytes)

{

befRow = posScan + stride * i;

}

if (rgbValues[befRow] < 255) rgbValues[befRow] = 255;

else break;

}

}

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

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

相关文章

《标准普通话教程》中对平舌音的发音方法的说明

《标准普通话教程》中关于平舌音的发音方法的描述&#xff1a; 第一个版本&#xff1a;大部分教材和老师 平舌音发音时&#xff0c;舌尖放在下齿背&#xff08;下齿龈&#xff09; 第二个版本&#xff1a;少部分教材和老师 平舌音发音时&#xff0c;舌尖放在下齿背&#xff0…

java javadoc_使用Java 9向Javadoc搜索添加术语

java javadoc有一个相对较旧的网页&#xff0c;称为“ Proposed Javadoc Tags ”&#xff0c;最初似乎是与Javadoc 1.2一起编写的&#xff0c;其中列出了“ Sun有朝一日可能会在Javadoc中实现的标签”。 在此列表中的标签是category &#xff0c; example &#xff0c; tutoria…

oracle system用户创建job 其他用户,oracle创建表空间、用户和表以及sys和system的区别...

一、oracle的3个内置账号(口令管理)scott(示范账户) tiger 内置账号system 系统管理员 操作用户sys 超级管理员 操作数据conn system/sasa;show user登录超级用户conn a/b as sysdba 或者 sysopera/b任何账号密码都可以(只能在服务端(安装数据的电脑)上运行更改用户密码&#x…

浅析 Linux 初始化系统(系统服务管理和控制程序/Init System) -- systemd

文章目录一、Systemd 的简介和特点&#xff08;一&#xff09;同 SysVinit 和 LSB init scripts 兼容&#xff08;二&#xff09;更快的启动速度&#xff08;三&#xff09;systemd 提供按需启动能力&#xff08;四&#xff09;Systemd 采用 Linux 的 Cgroup 特性跟踪和管理进程…

查询 service monitor 时发生内部错误_通过Service访问应用 (1)

目录通过Service访问应用通过Pod IP访问应用 通过ClusterIP Service在集群内部访问 通过Service访问应用通过之前的操作&#xff0c;应用部署完成了&#xff0c;我们的Demo网站已经成功启动了&#xff0c;那么如何访问网站呢&#xff1f;通过Pod IP访问应用我们可以通过Pod IP来…

jdk 8 时区 转换_使用JDK 8将收藏转换为地图

jdk 8 时区 转换我多次遇到这样的情况&#xff0c;希望将多个对象存储在Map中而不是Set或List中&#xff0c;因为将唯一标识信息的Map应用于对象有一些优势 。 Java 8通过流和Collectors.toMap&#xff08;…&#xff09;方法使翻译变得比以往更加容易。 使用Map而不是Set的一…

开源备份软件 oracle,oracle备份和恢复

最好把所有表删掉重新导入&#xff0c;表字段改变不会还原出来 &#xff0c;只会还原数据1 将数据库TEST完全导出,用户名system 密码manager 导出到D:\daochu.dmp中exp system/managerTest filed:\DB_backup\GWAMQA_Oracle\GWAM_Dev_201410311059.dmp fully2 将数据库中system用…

c语言 方程改main的值_C语言编程笔记丨编写第一个C语言程序hello world,我教你哇...

如果用C语言输出&#xff1a;Hello&#xff0c;world&#xff01;&#xff0c;该如何编写程序&#xff1f;**代码如下&#xff1a;**#include//包含标准库的信息main()//定义名为main的函数&#xff0c;不接受参数值{//main函数的语句都放在花括号中&#xff0c;也表示函数体的…

iPhone 手机/苹果手机如何设置来电铃声?

文章目录方法一、使用 APP 库乐队设置方法二、使用第三方软件「爱思助手」设置方法一、使用 APP 库乐队设置 详见《iPhone 手机设置铃声简易教程》 方法二、使用第三方软件「爱思助手」设置 详见《苹果 iPhone 手机怎么设置铃声》

linux定时创建文件,linux下如何创建定时任务

文/PM回忆录本篇文章不详细讲述cron服务的那种配置文件&#xff0c;只是应用层面的讲解&#xff0c;只求初步的掌握。说到定时任务&#xff0c;不能不介绍下cron&#xff1a;一、cron定时任务是什么在LINUX中&#xff0c;周期执行的任务一般由cron这个守护进程来处理[ps -ef|gr…

连接堡垒机出现java环境_Java 8:长期支持的堡垒

连接堡垒机出现java环境斯蒂芬科尔本 &#xff08; Stephen Colebourne &#xff09;的文章“ Java 9可以使用六个星期 ”开始&#xff0c;“ Java 9仅仅六个星期就已经过时了。” Colebourne参考了Mark Reinhold博客文章“ Moving Java Forwarding Faster ”&#xff0c;并写道…

assertj断言异常_编写自定义的AssertJ断言

assertj断言异常AssertJ是广泛使用的Hamcrest匹配器的替代匹配库。 实际上&#xff0c;对于我自己的项目&#xff0c;我已经更改为仅使用AssertJ-我只是发现流畅的界面和可扩展性非常吸引人。 您可以编写自定义断言&#xff0c;如下所示&#xff1a; 想象一下一种具有强度和饮…

Unix 发展简史

1965年时&#xff0c;贝尔实验室&#xff08;Bell Labs&#xff09;加入一项由通用电气&#xff08;General Electric&#xff09;和麻省理工学院&#xff08;MIT&#xff09;合作的项目&#xff1b;该项目要建立一套多使用者、多任务、多层次&#xff08;multi-user、multi-ta…

linux服务器不会中毒,[转载]ubuntu 不会中毒的原因(转)

ubuntu不会中毒的原因不是因为linux用户少&#xff0c;而是其它原因。如下是转载的高手的文章&#xff1a;可能不少人持这样一种观点&#xff0c;认 为 Linux病毒少是因为Linux不像Windows那么普及&#xff0c;其实这种观点很早已经被人批驳过了&#xff0c;一个最有力的论据是…

6-7 使用函数输出水仙花数_「Java」再议printf函数

System.out.printf() 是在JDK1.5版开始引入的方法&#xff0c;即在JDK1.5以后的版本才可以使用此函数&#xff0c;printf 方法有 printf(String format, Object ... args) 和 printf(Locale l, String format, Object ... args) 两种重载方式。其实学过C语言的小伙伴应该会觉得…

Debian GNU/Linux 的发展简史

Debian 是最早的 Linux 发行版之一&#xff0c;由 Ian Murdock&#xff08;伊恩默多克&#xff09; 创立。lan Murdock 于1973年4 月28日出生于德国的君斯坦市(Konstanz, Germany)。他是Debian GNU/Linux 发行版的创始人&#xff0c;也是商用Linux发行商Progeny公司的创始人。他…

jdk 细粒度锁_使用JDK 8轻松进行细粒度排序

jdk 细粒度锁Java的8的推出流和有用的静态 / 默认的方法比较接口可以很容易地根据个人的领域两个对象比较“值&#xff0c;而不需要实现一个比较&#xff08;T&#xff0c;T&#xff09;在其对象的类方法被比较。 我将使用一个简单的Song类来帮助演示这一点&#xff0c;接下来…

c语言命名规则_C语言的基本数据类型及变量

学习目标了解C语言的基本数据类型了解变量的基本概念了解变量的使用方法了解了变量的命名方法了解格式占位符了解变量的输出了解C语言程序的基本数据类型及概念的使用方法擦在C语言编程中&#xff0c;系统定义了多种数据类型&#xff0c;本节将讲解基本数据类型的分类。基本数据…

linux socket默认超时时间设置,Socket中如何设置连接超时 (转)

Socket中如何设置连接超时 (转)Socket中如何设置连接超时AntGhazi/2001.12.14 主页&#xff1a;antghazi.yeah把CSDN与中文翻了底朝天&#xff0c;也没找到如何设置socket的连接超时的满意方法&#xff0c;问此问题的兄弟已有一大堆&#xff0c;这里偶就讲一下win下如何设置soc…

Linux 常用的软件包管理器/软件包管理工具详解

文章目录RPM 是什么&#xff1f;应用于哪些系统RPM 的前端工具有哪些RPM 包命名规范RPM 安装软件的默认路径RPM 安装原理图RPM 命令详解YUM 是什么&#xff1f;应用于哪些系统YUM 原理说明主要特点YUM 和 RPM 的区别YUM 命令详解DNF 是什么应用于哪些系统DNF 命令详解APT 是什么…