GIT通过SSH克隆的方法
git clone ssh://服务器用户名@服务器地址:项目绝对路径
PHP HTTP类
<?php
class Libs_Http_Client {
private static $boundary = '';
public static function get($url, $params = array(), $headers = array(), $misc = array(), $cookie='') {
if (!empty($params)) {
$url = $url . '?' . http_build_query($params);
}
return self::http($url, 'GET', null, $headers, $misc, $cookie);
}
public static function post($url, $params, $files = array(), $headers = array(), $misc = array()) {
if (!$files) {
if (is_array($params) || is_object($params)) {
$body = http_build_query($params);
} else {
$body = $params;
}
} else {
$body = self::build_http_query_multi($params, $files);
$headers[] = "Content-Type: multipart/form-data; boundary=" . self::$boundary;
}
return self::http($url, 'POST', $body, $headers, $misc);
}
public static function postFiles($url, $files, $params = array(), $headers = array(), $misc = array()) {
if (!is_array($files)) {
return false;
}
foreach ($files as $key => &$val) {
$val = '@'.$val;
}
$body = array_merge($files, $params);
$headers[] = "Content-Type: multipart/form-data";
return self::http($url, 'POST', $body, $headers, $misc);
}
public static function getFiles($url, $files, $params = array(), $headers = array(), $misc = array()) {
if (!is_array($files)) {
return false;
}
foreach ($files as $key => &$val) {
$val = '@'.$val;
}
$body = array_merge($files, $params);
$headers[] = "Content-Type: multipart/form-data";
return self::http($url, 'GET', $body, $headers, $misc);
}
/**
* Make an HTTP request
*
* @return string API results
* @ignore
*/
private static function http($url, $method, $postfields = NULL, $headers = array(), $misc = array(), $cookie='') {
$ci = curl_init();
/* Curl settings */
curl_setopt($ci, CURLOPT_USERAGENT, 'Tdot Plum Client v0.1'); //HTTP头部user agent
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 30); //连接超时时间,单位秒
curl_setopt($ci, CURLOPT_TIMEOUT, 30); //最大执行时间,单位秒
curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE); //避免直接输出返回值
curl_setopt($ci, CURLOPT_ENCODING, ""); //可接受编码类型,空串支持所有类型
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, 2);
//curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));
curl_setopt($ci, CURLOPT_HEADER, FALSE);
switch ($method) {
case 'POST':
curl_setopt($ci, CURLOPT_POST, TRUE);
if (!empty($postfields)) {
curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
}
break;
}
foreach ($misc as $key => $val) {
$key = strtoupper($key);
switch ($key) {
case 'REFERER' :
curl_setopt($ci, CURLOPT_REFERER, $val);
break;
}
}
curl_setopt($ci, CURLOPT_URL, $url);
curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
if($cookie){
curl_setopt ($ci, CURLOPT_COOKIE , $cookie );
}
curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE);
$response = curl_exec($ci);
$httpCode = curl_getinfo($ci, CURLINFO_HTTP_CODE);
$httpInfo = curl_getinfo($ci);
curl_close ($ci);
return $response;
}
/**
* 发送文件时使用
* @param array $params
* @param array $files
* @return string
*/
private static function build_http_query_multi($params, $files) {
//if (!$params) return '';
self::$boundary = $boundary = uniqid('------------------');
$MPboundary = '--'.$boundary;
$endMPboundary = $MPboundary. '--';
$multipartbody = '';
foreach ($params as $key => $value) {
$multipartbody .= $MPboundary . "\r\n";
$multipartbody .= 'content-disposition: form-data; name="' . $key . "\"\r\n\r\n";
$multipartbody .= $value."\r\n";
}
foreach ($files as $key => $value) {
if (!$value) {continue;}
if (is_array($value)) {
$url = $value['url'];
if (isset($value['name'])) {
$filename = $value['name'];
} else {
$parts = explode( '?', basename($value['url']));
$filename = $parts[0];
}
$field = isset($value['field']) ? $value['field'] : $key;
} else {
$url = $value;
$parts = explode( '?', basename($url));
$filename = $parts[0];
$field = $key;
}
$content = file_get_contents($url);
$multipartbody .= $MPboundary . "\r\n";
$multipartbody .= 'Content-Disposition: form-data; name="' . $field . '"; filename="' . $filename . '"'. "\r\n";
$multipartbody .= "Content-Type: image/unknown\r\n\r\n";
$multipartbody .= $content. "\r\n";
}
$multipartbody .= $endMPboundary;
return $multipartbody;
}
}
BASH 批量替换文本文件DOS格式为UNIX格式
find ./ -type f -exec dos2unix {} \;
BASH 打包文件夹及文件夹内全部文件,上传至FTP服务器
BASH脚本打包文件夹及文件夹内全部文件并上传FTP服务器,用于快速下载服务器大文件的场景,如:服务器上有大小为2G,包含5万个文件的程序包,服务器带宽仅有2M,要快速下载这么大的文件夹,可先打包成ZIP压缩包,再上传至高带宽的文件服务器(如阿里云OSS),即可低成本高速完成下载过程。
下面以上传到阿里云OSS为例,在服务器上提前启动OSSFTP,然后运行下方代码的脚本
#!/bin/bash
ftpIP="127.0.0.1 2048"
uuid=$(cat /proc/sys/kernel/random/uuid)
filename="$(date +%s).${uuid^^}.zip"
function uploadFile {
ftp -v -n $ftpIP<<EOF
user OSS用户名 OSS密码
binary
passive
put $filename
bye
EOF
rm -rfv $filename
echo "此处是OSS链接$filename"
}
########################################################################
zip -r $filename 此处是被打包的文件夹名称
uploadFile
JAVA 图片拼接
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class MergeImageUtil {
/**
* 拼接图片(注:图片需长宽一致)
* @param files img1 ,img2
* @param type 1:横向拼接 2:纵向拼接
* @param targetFile 合成新的图片地址
*/
public static void mergeImage(String[] files, int type, String targetFile) {
int len = files.length;
if (len < 1) {
throw new RuntimeException("图片数量小于1");
}
File[] src = new File[len];
BufferedImage[] images = new BufferedImage[len];
int[][] ImageArrays = new int[len][];
for (int i = 0; i < len; i++) {
try {
src[i] = new File(files[i]);
images[i] = ImageIO.read(src[i]);
}
catch (Exception e) {
throw new RuntimeException(e);
}
int width = images[i].getWidth();
int height = images[i].getHeight();
ImageArrays[i] = new int[width * height];
ImageArrays[i] = images[i].getRGB(0, 0, width, height, ImageArrays[i], 0, width);
}
int newHeight = 0;
int newWidth = 0;
for (int i = 0; i < images.length; i++) {
// 横向
if (type == 1) {
newHeight = newHeight > images[i].getHeight() ? newHeight : images[i].getHeight();
newWidth += images[i].getWidth();
} else if (type == 2) {
// 纵向
newWidth = newWidth > images[i].getWidth() ? newWidth : images[i].getWidth();
newHeight += images[i].getHeight();
}
}
if (type == 1 && newWidth < 1) {
return;
}
if (type == 2 && newHeight < 1) {
return;
}
// 生成新图片
try {
BufferedImage ImageNew = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
int height_i = 0;
int width_i = 0;
for (int i = 0; i < images.length; i++) {
if (type == 1) {
ImageNew.setRGB(width_i, 0, images[i].getWidth(), newHeight, ImageArrays[i], 0,
images[i].getWidth());
width_i += images[i].getWidth();
} else if (type == 2) {
ImageNew.setRGB(0, height_i, newWidth, images[i].getHeight(), ImageArrays[i], 0, newWidth);
height_i += images[i].getHeight();
}
}
//输出想要的图片
ImageIO.write(ImageNew, targetFile.split("\\.")[1], new File(targetFile));
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Linux上对安卓安装包字节对齐、数字签名,用于开发云打包
字节对齐
zipalign -v 4 output.apk input.apk
数字签名
apksigner sign --ks keystore.jks --ks-key-alias 证书别名 --ks-pass pass:证书库密钥 --key-pass pass:证书密钥 --out output.apk input.apk
Linux上利用screen一键启动程序
#!/bin/bash
cd 程序所在目录
screen_name="窗口名"
screen -dmS $screen_name
screen -x $screen_name -p 0 -X stuff "shell命令"
screen -x $screen_name -p 0 -X stuff "\n"
Java 身份证信息处理类
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* @author QiFeng·Luo
*/
public class IDCardUtil {
/**
* 数字
*/
public final static Pattern NUMBERS = Pattern.compile("\\d+");
/**
* 中国公民身份证号码最小长度。
*/
private static final int CHINA_ID_MIN_LENGTH = 15;
/**
* 中国公民身份证号码最大长度。
*/
private static final int CHINA_ID_MAX_LENGTH = 18;
public static Exception isValidatedAllIdcard(String idcard) throws Exception {
boolean ret = isIdcard(idcard);
if (!ret) {
throw new Exception("身份证格式有误");
}
return null;
}
final static Map<Integer, String> zoneNum = new HashMap<>();
/**
* 身份证省份编码
* */
static {
zoneNum.put(11, "北京");
zoneNum.put(12, "天津");
zoneNum.put(13, "河北");
zoneNum.put(14, "山西");
zoneNum.put(15, "内蒙古");
zoneNum.put(21, "辽宁");
zoneNum.put(22, "吉林");
zoneNum.put(23, "黑龙江");
zoneNum.put(31, "上海");
zoneNum.put(32, "江苏");
zoneNum.put(33, "浙江");
zoneNum.put(34, "安徽");
zoneNum.put(35, "福建");
zoneNum.put(36, "江西");
zoneNum.put(37, "山东");
zoneNum.put(41, "河南");
zoneNum.put(42, "湖北");
zoneNum.put(43, "湖南");
zoneNum.put(44, "广东");
zoneNum.put(45, "广西");
zoneNum.put(46, "海南");
zoneNum.put(50, "重庆");
zoneNum.put(51, "四川");
zoneNum.put(52, "贵州");
zoneNum.put(53, "云南");
zoneNum.put(54, "西藏");
zoneNum.put(61, "陕西");
zoneNum.put(62, "甘肃");
zoneNum.put(63, "青海");
zoneNum.put(64, "宁夏");
zoneNum.put(65, "新疆");
zoneNum.put(71, "台湾");
zoneNum.put(81, "香港");
zoneNum.put(82, "澳门");
zoneNum.put(91, "国外");
}
/**
* 校验码
*/
final static int[] PARITYBIT = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
/**
* 加权因子wi
*/
final static int[] POWER_LIST = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
/**
* 验证身份证号有效性
*
* @param idCard:身份证号
* @return true/false
*/
public static boolean isIdcard(String idCard) {
// 号码长度应为15位或18位
if (idCard == null || (idCard.length() != 15 && idCard.length() != 18)) {
return false;
}
// 校验区位码
if (!zoneNum.containsKey(Integer.valueOf(idCard.substring(0, 2)))) {
return false;
}
// 校验年份
String year = idCard.length() == 15 ? "19" + idCard.substring(6, 8) : idCard.substring(6, 10);
final int iyear = Integer.parseInt(year);
if (iyear < 1900 || iyear > Calendar.getInstance().get(Calendar.YEAR)) {
// 1900年的PASS,超过今年的PASS
return false;
}
// 校验月份
String month = idCard.length() == 15 ? idCard.substring(8, 10) : idCard.substring(10, 12);
final int imonth = Integer.parseInt(month);
if (imonth < 1 || imonth > 12) {
return false;
}
// 校验天数
String day = idCard.length() == 15 ? idCard.substring(10, 12) : idCard.substring(12, 14);
final int iday = Integer.parseInt(day);
if (iday < 1 || iday > 31) {
return false;
}
// 校验一个合法的年月日
if (!isValidDate(year + month + day)) {
return false;
}
// 校验位数
int power = 0;
final char[] cs = idCard.toUpperCase().toCharArray();
for (int i = 0; i < cs.length; i++) {// 循环比正则表达式更快
if (i == cs.length - 1 && cs[i] == 'X') {
break;// 最后一位可以是X或者x
}
if (cs[i] < '0' || cs[i] > '9') {
return false;
}
if (i < cs.length - 1) {
power += (cs[i] - '0') * POWER_LIST[i];
}
}
// 校验“校验码”
if (idCard.length() == 15) {
return true;
}
return cs[cs.length - 1] == PARITYBIT[power % 11];
}
/**
* 判断字符串是否为日期格式(合法)
*
* @param inDate:字符串时间
* @return true/false
*/
public static boolean isValidDate(String inDate) {
if (inDate == null) {
return false;
}
// 或yyyy-MM-dd
SimpleDateFormat dataFormat = new SimpleDateFormat("yyyyMMdd");
if (inDate.trim().length() != dataFormat.toPattern().length()) {
return false;
}
// 该方法用于设置Calendar严格解析字符串;默认为true,宽松解析
dataFormat.setLenient(false);
try {
dataFormat.parse(inDate.trim());
} catch (ParseException e) {
return false;
}
return true;
}
/**
* 转换成日期
* @param birthday
* @return
*/
private static Date toBirthDay(String birthday){
try{
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, Integer.parseInt(birthday.substring(0, 4)));
// 月份从0开始,所以减1
calendar.set(Calendar.MONTH, Integer.parseInt(birthday.substring(4, 6)) - 1);
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(birthday.substring(6, 8)));
// 以下设置时分秒,但是对生日的意义不大
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}catch (Exception e){
return null;
}
}
/**
* 给定内容是否匹配正则
*
* @param pattern 模式
* @param content 内容
* @return 正则为null或者""则不检查,返回true,内容为null返回false
*/
private static boolean isMatch(Pattern pattern, CharSequence content) {
if (content == null || pattern == null) {
// 提供null的字符串为不匹配
return false;
}
return pattern.matcher(content).matches();
}
/**
* 将字符串转换成指定格式的日期
*
* @param str 日期字符串.
* @param dateFormat 日期格式. 如果为空,默认为:yyyy-MM-dd HH:mm:ss.
* @return
*/
private static Date strToDate(final String str, String dateFormat) {
if (str == null || str.trim().length() == 0) {
return null;
}
try {
if (dateFormat == null || dateFormat.length() == 0) {
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
DateFormat fmt = new SimpleDateFormat(dateFormat);
return fmt.parse(str.trim());
} catch (Exception ex) {
return null;
}
}
/**
* 根据日期获取年
*
* @param date 日期
* @return 年的部分
*/
public static int year(Date date) {
Calendar ca = Calendar.getInstance();
ca.setTime(date);
return ca.get(Calendar.YEAR);
}
/**
* 将power和值与11取模获得余数进行校验码判断
*
* @param iSum 加权和
* @return 校验位
*/
private static char getCheckCode18(int iSum) {
switch (iSum % 11) {
case 10:
return '2';
case 9:
return '3';
case 8:
return '4';
case 7:
return '5';
case 6:
return '6';
case 5:
return '7';
case 4:
return '8';
case 3:
return '9';
case 2:
return 'x';
case 1:
return '0';
case 0:
return '1';
default:
return ' ';
}
}
/**
* 获得18位身份证校验码
* 计算方式:
* 将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
* 将这17位数字和系数相乘的结果相加
* 用加出来和除以11,看余数是多少
* 余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2
* 通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2
* @param code17 18位身份证号中的前17位
* @return 第18位
*/
private static char getCheckCode18(String code17) {
int sum = getPowerSum(code17.toCharArray());
return getCheckCode18(sum);
}
/**
* 将身份证的每位和对应位的加权因子相乘之后,再得到和值
*
* @param iArr 身份证号码的数组
* @return 身份证编码
*/
private static int getPowerSum(char[] iArr) {
int iSum = 0;
if (POWER_LIST.length == iArr.length) {
for (int i = 0; i < iArr.length; i++) {
iSum += Integer.valueOf(String.valueOf(iArr[i])) * POWER_LIST[i];
}
}
return iSum;
}
/**
* 将15位身份证号码转换为18位
*
* @param idCard 15位身份编码
* @return 18位身份编码
*/
public static String convertIdCard(String idCard) {
StringBuilder idCard18;
if (idCard.length() != CHINA_ID_MIN_LENGTH) {
return null;
}
if (isMatch(NUMBERS, idCard)) {
// 获取出生年月日
String birthday = idCard.substring(6, 12);
Date birthDate = strToDate(birthday, "yyMMdd");
// 获取出生年
int sYear = year(birthDate);
// 理论上2000年之后不存在15位身份证,可以不要此判断
if (sYear > 2000) {
sYear -= 100;
}
idCard18 = new StringBuilder().append(idCard, 0, 6).append(sYear).append(idCard.substring(8));
// 获取校验位
char sVal = getCheckCode18(idCard18.toString());
idCard18.append(sVal);
} else {
return null;
}
return idCard18.toString();
}
/**
* 从身份证号码中获取生日
* @param idno
* @return null表示idno错误,未获取到生日
*/
public static Date getBirthDay(String idno){
if(!isIdcard(idno)){
return null;
}
if (idno.length() == 15) {
// 如果是15位转为18位
idno = convertIdCard(idno);
}
return toBirthDay(idno.substring(6, 14));
}
/**
* 从身份证号码中获取生日
* @param idno
* @return null表示idno错误,未获取到生日 日期格式为:yyyy-MM-dd
*/
public static String getBirthDayStr(String idno){
if(!isIdcard(idno)){
return null;
}
if (idno.length() == 15) {
// 如果是15位转为18位
idno = convertIdCard(idno);
}
Date birthday = toBirthDay(idno.substring(6, 14));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
return simpleDateFormat.format(birthday);
}
/**
* 从身份证号中获取性别
* @param idno
* @return 0:男,1:女,-1:证件号码错误
*/
public static String getGender(String idno){
if(!isIdcard(idno)){
return "-1";
}
if (idno.length() == 15) {
// 如果是15位转为18位
idno = convertIdCard(idno);
}
// 奇男,偶女
return (Integer.parseInt(idno.substring(16, 17)) % 2) == 0 ? "1" : "0";
}
/**
* 方法调用测试
* */
public static void main(String[] args) {
String idc= "130503670401001";
//检查身份证是否合规
boolean idcard = isIdcard(idc);
if (idcard) {
System.out.println("身份证号码合规");
// 获取身份证号码中的生日
Date birthDay = getBirthDay(idc);
System.out.println("当前身份证的生日为:"+ getBirthDayStr(idc));
// 获取性别
String gender = getGender(idc);
if ("0".equals(gender)) {
System.out.println("当前身份证的性别为:男性");
} else if ("1".equals(gender)) {
System.out.println("当前身份证的性别为:女性");
} else {
System.out.println("当前身份证格式不正确");
}
}else {
System.out.println("身份证格式有误");
}
}
}
Java Canny边缘检测
import java.awt.image.BufferedImage;
public class CannyUtil {
int Y;
int X;
int src[][];
int dest[][];
double tan[][];
BufferedImage bufferedImage;
BufferedImage bufferedImage_old;
public CannyUtil(BufferedImage bi) {
bufferedImage_old = bi;
bufferedImage = bi;
Y = bi.getWidth();
X = bi.getHeight();
src = new int[Y][X];
dest = new int[Y][X];
tan = new double[Y][X];
}
//灰度
public BufferedImage Gray() {
for(int y=0;y<Y;y++) {
for(int x=0;x<X;x++) {
int r=(bufferedImage.getRGB(y,x)>>16)&0x000000ff;
int g=(bufferedImage.getRGB(y,x)>>8)&0x000000ff;
int b=bufferedImage.getRGB(y,x)&0x000000ff;
src[y][x]=(int)(0.2989*r+0.587*g+0.114*b);
//bufferedImage.setRGB(y,x,0xff000000|src[y][x]|(src[y][x]<<8)|(src[y][x]<<16));
}
}
return bufferedImage;
}
//高斯平滑
public BufferedImage Gauss()
{
int M[][]={{1,2,1},{2,4,2},{1,2,1}};
bufferedImage=new BufferedImage(Y,X,BufferedImage.TYPE_INT_RGB);
for(int y=1;y<Y-1;y++)
for(int x=1;x<X-1;x++)
{
dest[y][x]= src[y-1][x-1]*M[0][0]+src[y][x-1]*M[1][0]+src[y+1][x-1]*M[2][0]
+src[y-1][x] *M[0][1]+src[y][x] *M[1][1]+src[y+1][x] *M[2][1]
+src[y-1][x+1]*M[0][2]+src[y][x+1]*M[1][2]+src[y+1][x+1]*M[2][2];
dest[y][x]/=16;
bufferedImage.setRGB(y,x,0xff000000|dest[y][x]|(dest[y][x]<<8)|(dest[y][x]<<16));
}
for(int y=1;y<Y-1;y++)
for(int x=1;x<X-1;x++)
src[y][x]=dest[y][x];
return bufferedImage;
}
//索贝尔边缘提取
public BufferedImage Sobel()
{
int Mx[][]={{-1,0,1},{-2,0,2},{-1,0,1}};
int My[][]={{-1,-2,-1},{0,0,0},{1,2,1}};
bufferedImage=new BufferedImage(Y,X,BufferedImage.TYPE_INT_RGB);
for(int y=1;y<Y-1;y++)
for(int x=1;x<X-1;x++)
{
int dx= src[y-1][x-1]*Mx[0][0]+src[y][x-1]*Mx[1][0]+src[y+1][x-1]*Mx[2][0]
+src[y-1][x] *Mx[0][1]+src[y][x] *Mx[1][1]+src[y+1][x] *Mx[2][1]
+src[y-1][x+1]*Mx[0][2]+src[y][x+1]*Mx[1][2]+src[y+1][x+1]*Mx[2][2];
int dy= src[y-1][x-1]*My[0][0]+src[y][x-1]*My[1][0]+src[y+1][x-1]*My[2][0]
+src[y-1][x] *My[0][1]+src[y][x] *My[1][1]+src[y+1][x] *My[2][1]
+src[y-1][x+1]*My[0][2]+src[y][x+1]*My[1][2]+src[y+1][x+1]*My[2][2];
dest[y][x]=(int)(Math.sqrt(dx*dx+dy*dy)+0.5);
if(dest[y][x]>255) dest[y][x]=255;
if(dest[y][x]<0) dest[y][x]=0;
bufferedImage.setRGB(y,x,0xff000000|dest[y][x]|(dest[y][x]<<8)|(dest[y][x]<<16));
tan[y][x]=1.0*dy/dx;
}
for(int y=1;y<Y-1;y++)
for(int x=1;x<X-1;x++)
src[y][x]=dest[y][x];
return bufferedImage;
}
//非极大值抑制
public BufferedImage NMS()
{
for(int y=1;y<Y-1;y++)
for(int x=1;x<X-1;x++)
{
if(Math.abs(tan[y][x])<=0.5)
{
if(src[y][x]>=src[y][x-1]&&src[y][x]>=src[y][x+1])
dest[y][x]=src[y][x];
else
dest[y][x]=0;
}
else if(-2<=tan[y][x]&&tan[y][x]<=-0.5)
{
if(src[y][x]>=src[y+1][x-1]&&src[y][x]>=src[y-1][x+1])
dest[y][x]=src[y][x];
else
dest[y][x]=0;
}
else if(0.5<=tan[y][x]&&tan[y][x]<=2)
{
if(src[y][x]>=src[y-1][x-1]&&src[y][x]>=src[y+1][x+1])
dest[y][x]=src[y][x];
else
dest[y][x]=0;
}
else if(2<=Math.abs(tan[y][x]))
{
if(src[y][x]>=src[y-1][x]&&src[y][x]>=src[y+1][x])
dest[y][x]=src[y][x];
else
dest[y][x]=0;
}
bufferedImage.setRGB(y,x,0xff000000|dest[y][x]|(dest[y][x]<<8)|(dest[y][x]<<16));
}
for(int y=1;y<Y-1;y++)
for(int x=1;x<X-1;x++)
src[y][x]=dest[y][x];
return bufferedImage;
}
//双阈值连接
public BufferedImage DT()
{
int th1=127;
int th2=63;
for(int y=1;y<Y-1;y++)
for(int x=1;x<X-1;x++)
{
if(src[y][x]>=th1)
dest[y][x]=255;
else if(src[y][x]<=th2)
dest[y][x]=0;
else
{
if(src[y-1][x-1]>=th1||src[y-1][x]>=th1||src[y-1][x+1]>=th1||src[y][x-1]>=th1||src[y][x+1]>=th1||src[y+1][x-1]>=th1||src[y+1][x]>=th1||src[y+1][x+1]>=th1)
dest[y][x]=255;
else
dest[y][x]=0;
}
bufferedImage.setRGB(y,x,0xff000000|dest[y][x]|(dest[y][x]<<8)|(dest[y][x]<<16));
}
for(int y=1;y<Y-1;y++)
for(int x=1;x<X-1;x++)
src[y][x]=dest[y][x];
return bufferedImage;
}
//自动裁剪
public BufferedImage autoClip(int GaussCount) {
bufferedImage = Gray();
for(int i=0;i<GaussCount;i++) {
bufferedImage = Gauss();
}
bufferedImage = Sobel();
bufferedImage = NMS();
bufferedImage = DT();
boolean minXb = false, minYb = false;
int minX = 0, minY = 0, maxX = 0, maxY = 0;
for (int x = 0; x < bufferedImage.getWidth(); x++) {
for (int y = 0; y < bufferedImage.getHeight(); y++) {
// 如果是透明像素 跳过
if (bufferedImage.getRGB(x,y) == 0) continue;
// 获取该点像素,并以object类型表示
Object data = bufferedImage.getRaster().getDataElements(x, y, null);
int r = bufferedImage.getColorModel().getRed(data);
int g = bufferedImage.getColorModel().getGreen(data);
int b = bufferedImage.getColorModel().getBlue(data);
if (r == 0 && g == 0 && b == 0) continue;
if (!minXb) {
minX = x;
minXb = true;
}
if (!minYb) {
minY = y;
minYb = true;
}
minX = Math.min(minX, x);
minY = Math.min(minY, y);
maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);
}
}
System.out.printf("minX=%d,minY=%d,maxX=%d,maxY=%d\n", minX,minY,maxX,maxY);
return bufferedImage_old.getSubimage(minX, minY, maxX - minX, maxY - minY);
}
}