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);
}
}
Java 文件操作工具类
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.io.FileUtils;
import com.bcap_systemlib.config.Configuration;
public class FileUtil {
/**
* 将多个文件打包到一个zip中
*
* @param sourceFolder
* @param zipFile
* @return
* @throws Exception
*/
public static boolean zipFile(String sourceFolder, File zipFile) throws Exception{
boolean isOk = true;
File f = new File(sourceFolder);
ZipOutputStream out = null;
try{
if(!f.exists()){
f.mkdirs();
}
out = new ZipOutputStream(new FileOutputStream(zipFile));
zip(out, f, "");
out.flush();
FileUtils.deleteDirectory(f);
} catch (Exception e){
e.printStackTrace();
throw new Exception("压缩文件出错!");
} finally
{
if(null != out){
try{ out.close(); } catch (Exception e){ e.printStackTrace();}
}
}
return isOk;
}
/**
* 递归压缩文件
* @param out
* @param f
* @param base
* @throws Exception
*/
private static void zip(ZipOutputStream out, File f, String base) throws Exception {
if (f.isDirectory()) {
File[] fl = f.listFiles();
out.putNextEntry(new ZipEntry(base + "/"));
base = base.length() == 0 ? "" : base + "/";
for (int i = 0; i < fl.length; i++) {
zip(out, fl[i], base + fl[i].getName());
}
}else {
out.putNextEntry(new ZipEntry(base));
FileInputStream in = new FileInputStream(f);
int b;
while ( (b = in.read()) != -1) {
out.write(b);
}
in.close();
}
}
/**
* 下载单个文件
*
* @param file
* @param request
* @param response
* @return
*/
public static boolean downFile(File file, HttpServletRequest request, HttpServletResponse response) {
boolean isOk = true;
OutputStream myout = null;
FileInputStream fis = null;
BufferedInputStream buff = null;
HttpSession session = request.getSession();
if (session != null) {
session.setAttribute("state", "");
}
try {
response.setContentType("application/x-msdownload");
response.setContentLength((int) file.length());
response.setHeader("content-disposition", "attachment;filename=" + EncodingConvertUtil.utf2iso(file.getName()));
fis = new FileInputStream(file);
buff = new BufferedInputStream(fis);
byte[] b = new byte[1024 * 10];//相当于我们的缓存
long k = 0;//该值用于计算当前实际下载了多少字节
//从response对象中得到输出流,准备下载
myout = response.getOutputStream();
while (k < file.length()) {
int j = buff.read(b, 0, b.length);
k += j;
//将b中的数据写到客户端的内存
myout.write(b, 0, j);
}
myout.flush();
} catch (Exception e) {
e.printStackTrace();
isOk = false;
} finally {
try {
if (null != myout) {
myout.close();
myout = null;
}
if (null != buff) {
buff.close();
buff = null;
}
if (null != fis) {
fis.close();
fis = null;
}
if(file.exists()){
FileUtil.delFile(file);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return isOk;
}
/**
* 删除单个文件
*
* @param file
* @return
*/
public static boolean delFile(File file) {
boolean isOk = true;
try {
if (file.isFile() && file.exists()) {
file.delete();
}
} catch (Exception e) {
e.printStackTrace();
isOk = false;
} finally {
// log ...
}
return isOk;
}
public static void downloadFileFromRemote(String remoteFilePath, String localFilePath){
URL urlfile = null;
HttpURLConnection httpUrl = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
File f = new File(localFilePath);
try
{
urlfile = new URL(remoteFilePath);
httpUrl = (HttpURLConnection)urlfile.openConnection();
httpUrl.connect();
bis = new BufferedInputStream(httpUrl.getInputStream());
bos = new BufferedOutputStream(new FileOutputStream(f));
int len = 2048;
byte[] b = new byte[len];
while ((len = bis.read(b)) != -1)
{
bos.write(b, 0, len);
}
System.out.println("下载成功");
bos.flush();
bis.close();
httpUrl.disconnect();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
bis.close();
bos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public static void writeFile(String filePathAndName, String fileContent) {
try {
File f = new File(filePathAndName);
if (!f.exists()) {
f.createNewFile();
}
OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(f),Configuration.SERVLET_CHARACTER_ENCODING);
BufferedWriter writer=new BufferedWriter(write);
writer.write(fileContent);
writer.close();
} catch (Exception e) {
System.out.println("写文件内容操作出错");
e.printStackTrace();
}
}
public static String readFile(String filePathAndName) {
String fileContent = "";
try {
File f = new File(filePathAndName);
if(f.isFile()&&f.exists()){
InputStreamReader read = new InputStreamReader(new FileInputStream(f),Configuration.SERVLET_CHARACTER_ENCODING);
BufferedReader reader=new BufferedReader(read);
String line;
while ((line = reader.readLine()) != null) {
fileContent += line;
}
read.close();
}
} catch (Exception e) {
System.out.println("读取文件内容操作出错");
e.printStackTrace();
}
return fileContent;
}
public static String getExtName(String filename) {
int index = filename.lastIndexOf(".");
if (index == -1) {
return null;
}
String result = filename.substring(index);
return result;
}
}