ftp&圖片文件處理工具類

圖片處理工具類:

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import sun.misc.BASE64Decoder;

/**
 * 圖片處理工具類:<br>
 * 功能:縮放圖像、切割圖像、圖像類型轉換、彩色轉黑白、文字水印、圖片水印等
 */
public class ImageUtils {
	/**
	 * 幾種常見的圖片格式
	 */
	public static String IMAGE_TYPE_GIF = "gif";// 圖形交換格式

	public static String IMAGE_TYPE_JPG = "jpg";// 聯合照片專家組

	public static String IMAGE_TYPE_JPEG = "jpeg";// 聯合照片專家組

	public static String IMAGE_TYPE_BMP = "bmp";// 英文Bitmap(位圖)的簡寫,它是Windows操作系統中的標準圖像文件格式

	public static String IMAGE_TYPE_PNG = "png";// 可移植網絡圖形

	public static String IMAGE_TYPE_PSD = "psd";// Photoshop的專用格式Photoshop

	/**
	 * 程序入口:用於測試
	 * 
	 * @param args
	 */
	///public static void main(String[] args) {
		// 1-縮放圖像:
		// 方法一:按比例縮放
		// ImageUtils.scale("d:/31F6A615B6264FED8FDEAED245398F9F.jpg",
		// "d:/abc_scale.jpg", 120);// 測試OK
		// 方法二:按高度和寬度縮放
		// ImageUtils.scale2("d:/31F6A615B6264FED8FDEAED245398F9F.jpg",
		// "d:/abc_scale2.jpg", 500, 300, true);// 測試OK
		// 2-切割圖像:
		// 方法一:按指定起點座標和寬高切割
		// ImageUtils.cut("d:/31F6A615B6264FED8FDEAED245398F9F.jpg",
		// "d:/abc_cut.jpg", 0, 0, 400, 400);// 測試OK
		// 方法二:指定切片的行數和列數
		// ImageUtils.cut2("d:/31F6A615B6264FED8FDEAED245398F9F.jpg", "d:/", 2,
		// 2);// 測試OK
		// 方法三:指定切片的寬度和高度
		// ImageUtils.cut3("d:/31F6A615B6264FED8FDEAED245398F9F.jpg", "d:/",
		// 300, 300);// 測試OK
		// 3-圖像類型轉換:
		// ImageUtils.convert("d:/31F6A615B6264FED8FDEAED245398F9F.jpg", "GIF",
		// "d:/abc_convert.gif");// 測試OK
		// 4-彩色轉黑白:
		// ImageUtils.gray("d:/31F6A615B6264FED8FDEAED245398F9F.jpg",
		// "d:/abc_gray.jpg");// 測試OK
		// 5-給圖片添加文字水印:
		// 方法一:
		// ImageUtils.pressText(***(BAOSAAS-VAS)",
		// "d:/147A521409B0492490807F9ABBECFEA6-0.jpg", "d:/text.jpg", "宋體",
		// Font.BOLD, Color.blue, 30, 0, 25, 0.4f);// 測試OK
		//ImageUtils.pressText("***", "d:/stock.jpg", "d:/text.jpg", "宋體", Font.BOLD, Color.blue, 60, 0, 0, 0.2f, 25, 10);// 測試OK
		// 方法二:
		// ImageUtils.pressText2("我也是水印文字",
		// "d:/31F6A615B6264FED8FDEAED245398F9F.jpg", "d:/abc_pressText2.jpg",
		// "黑體", 36, Color.white, 80, 0, 0, 0.5f);// 測試OK

		// 6-給圖片添加圖片水印:
		// ImageUtils.pressImage("d:/abc2.jpg",
		// "d:/31F6A615B6264FED8FDEAED245398F9F.jpg", "d:/abc_pressImage.jpg",
		// 0, 0, 0.5f);// 測試OK
	//}

	/**
	 * 縮放圖像(按比例縮放)
	 * 
	 * @param srcImageFile
	 *            源圖像文件地址
	 * @param result
	 *            縮放後的圖像地址
	 * @param scale
	 *            縮放比例
	 * @param flag
	 *            縮放選擇:true 放大; false 縮小;
	 */
	public final static void scale(String srcImageFile, String result, int width) {
		try {
			BufferedImage src = ImageIO.read(new File(srcImageFile)); // 讀入文件
			// int orgWidth = src.getWidth(); // 得到源圖寬
			// if (orgWidth > width) {
			int height = src.getHeight() * width / src.getWidth(); // 得到源圖長
			// if (flag) {// 放大
			// width = width * scale;
			// height = height * scale;
			// } else {// 縮小
			// width = width / scale;
			// height = height / scale;
			// }
			Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
			BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			Graphics g = tag.getGraphics();
			g.drawImage(image, 0, 0, null); // 繪製縮小後的圖
			g.dispose();
			ImageIO.write(tag, "JPEG", new File(result));// 輸出到文件流
			// } else {
			// try {
			// FileUntil.copyFile(srcImageFile, result);
			// } catch (Exception e) {
			// e.printStackTrace();
			// }
			// }
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 縮放圖像(按高度和寬度縮放)
	 * 
	 * @param srcImageFile
	 *            源圖像文件地址
	 * @param result
	 *            縮放後的圖像地址
	 * @param height
	 *            縮放後的高度
	 * @param width
	 *            縮放後的寬度
	 * @param bb
	 *            比例不對時是否需要補白:true爲補白; false爲不補白;
	 */
	public final static void scale(String srcImageFile, String result, int width, int height) {
		scale(srcImageFile, result, width, height, false);
	}

	public final static void scale(String srcImageFile, String result, int width, int height, boolean bb) {
		try {
			double ratio = 0.0; // 縮放比例
			File f = new File(srcImageFile);
			BufferedImage bi = ImageIO.read(f);
			Image itemp = bi.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
			// 計算比例
			if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
				if (bi.getHeight() > bi.getWidth()) {
					ratio = (new Integer(height)).doubleValue() / bi.getHeight();
				} else {
					ratio = (new Integer(width)).doubleValue() / bi.getWidth();
				}
				AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
				itemp = op.filter(bi, null);
			}
			if (bb) {// 補白
				BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				Graphics2D g = image.createGraphics();
				g.setColor(Color.white);
				g.fillRect(0, 0, width, height);
				if (width == itemp.getWidth(null))
					g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), Color.white, null);
				else
					g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), Color.white, null);
				g.dispose();
				itemp = image;
			}
			String imgType = srcImageFile.substring(srcImageFile.lastIndexOf(".") + 1, srcImageFile.length()); // 默認
																												// JPEG
			BufferedImage im = bi;
			if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
				im = (BufferedImage) itemp;
			}
			ImageIO.write(im, imgType, new File(result));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 圖像切割(按指定起點座標和寬高切割)
	 * 
	 * @param srcImageFile
	 *            源圖像地址
	 * @param result
	 *            切片後的圖像地址
	 * @param x
	 *            目標切片起點座標X
	 * @param y
	 *            目標切片起點座標Y
	 * @param width
	 *            目標切片寬度
	 * @param height
	 *            目標切片高度
	 */
	public final static void cut(String srcImageFile, String result, int x, int y, int width, int height) {
		try {
			// 讀取源圖像
			BufferedImage bi = ImageIO.read(new File(srcImageFile));
			int srcWidth = bi.getHeight(); // 源圖寬度
			int srcHeight = bi.getWidth(); // 源圖高度
			if (srcWidth > 0 && srcHeight > 0) {
				Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
				// 四個參數分別爲圖像起點座標和寬高
				// 即: CropImageFilter(int x,int y,int width,int height)
				ImageFilter cropFilter = new CropImageFilter(x, y, width, height);
				Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
				BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				Graphics g = tag.getGraphics();
				g.drawImage(img, 0, 0, width, height, null); // 繪製切割後的圖
				g.dispose();
				// 輸出爲文件
				ImageIO.write(tag, "JPEG", new File(result));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 切割圖片
	 * 
	 * @param srcImageFile
	 * @param result
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @param imgType
	 */
	public final static void cut(String srcImageFile, String result, int x, int y, int width, int height, String imgType) {
		try {
			// 讀取源圖像
			BufferedImage bi = ImageIO.read(new File(srcImageFile));
			int srcImgW = bi.getWidth(); // 源圖寬度
			int srcImgH = bi.getHeight(); // 源圖高度
			int tmpImgW = width;
			int tmpImgH = height;
			int dstImgW = width; // 190
			int dstImgH = height; // 147
			int srcX = x;
			int srcY = y;
			int srcW = 0;
			int srcH = 0;
			int dstX = 0;
			int dstY = 0;
			int dstW = 0;
			int dstH = 0;
			if (srcX <= -tmpImgW || srcX > srcImgW) {
				srcX = srcW = dstX = dstW = 0;
			} else if (srcX <= 0) {
				dstX = -srcX;
				srcX = 0;
				srcW = dstW = Math.min(srcImgW, tmpImgW + srcX);
			} else if (srcX <= srcImgW) {
				dstX = 0;
				srcW = dstW = Math.min(tmpImgW, srcImgW - srcX);
			}

			if (srcW <= 0 || srcY <= -tmpImgH || srcY > srcImgH) {
				srcY = srcH = dstY = dstH = 0;
			} else if (srcY <= 0) {
				dstY = -srcY;
				srcY = 0;
				srcH = dstH = Math.min(srcImgH, tmpImgH + srcY);
			} else if (srcY <= srcImgH) {
				dstY = 0;
				srcH = dstH = Math.min(tmpImgH, srcImgH - srcY);
			}
			float ratio = (float) tmpImgW / dstImgW;
			dstX = (int) ((float) dstX / ratio);
			dstY = (int) ((float) dstY / ratio);
			dstW = (int) ((float) dstW / ratio);
			dstH = (int) ((float) dstH / ratio);

			// Image itemp = bi.getScaledInstance(width, height,
			// BufferedImage.SCALE_SMOOTH);
			Image image = bi.getScaledInstance(srcImgW, srcImgH, Image.SCALE_DEFAULT);
			ImageFilter cropFilter = new CropImageFilter(srcX, srcY, srcW, srcH);
			Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
			BufferedImage tag = new BufferedImage(dstImgW, dstImgH, BufferedImage.TYPE_INT_RGB);
			Graphics g = tag.getGraphics();
			g.drawImage(img, dstX, dstY, dstW, dstH, null);
			g.dispose();
			// 輸出爲文件
			ImageIO.write(tag, imgType, new File(result));

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 圖像切割(指定切片的行數和列數)
	 * 
	 * @param srcImageFile
	 *            源圖像地址
	 * @param descDir
	 *            切片目標文件夾
	 * @param rows
	 *            目標切片行數。默認2,必須是範圍 [1, 20] 之內
	 * @param cols
	 *            目標切片列數。默認2,必須是範圍 [1, 20] 之內
	 */
	public final static void cut2(String srcImageFile, String descDir, int rows, int cols) {
		try {
			if (rows <= 0 || rows > 20)
				rows = 2; // 切片行數
			if (cols <= 0 || cols > 20)
				cols = 2; // 切片列數
			// 讀取源圖像
			BufferedImage bi = ImageIO.read(new File(srcImageFile));
			int srcWidth = bi.getHeight(); // 源圖寬度
			int srcHeight = bi.getWidth(); // 源圖高度
			if (srcWidth > 0 && srcHeight > 0) {
				Image img;
				ImageFilter cropFilter;
				Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
				int destWidth = srcWidth; // 每張切片的寬度
				int destHeight = srcHeight; // 每張切片的高度
				// 計算切片的寬度和高度
				if (srcWidth % cols == 0) {
					destWidth = srcWidth / cols;
				} else {
					destWidth = (int) Math.floor(srcWidth / cols) + 1;
				}
				if (srcHeight % rows == 0) {
					destHeight = srcHeight / rows;
				} else {
					destHeight = (int) Math.floor(srcWidth / rows) + 1;
				}
				// 循環建立切片
				// 改進的想法:是否可用多線程加快切割速度
				for (int i = 0; i < rows; i++) {
					for (int j = 0; j < cols; j++) {
						// 四個參數分別爲圖像起點座標和寬高
						// 即: CropImageFilter(int x,int y,int width,int height)
						cropFilter = new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight);
						img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
						BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
						Graphics g = tag.getGraphics();
						g.drawImage(img, 0, 0, null); // 繪製縮小後的圖
						g.dispose();
						// 輸出爲文件
						ImageIO.write(tag, "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg"));
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 圖像切割(指定切片的寬度和高度)
	 * 
	 * @param srcImageFile
	 *            源圖像地址
	 * @param descDir
	 *            切片目標文件夾
	 * @param destWidth
	 *            目標切片寬度。默認200
	 * @param destHeight
	 *            目標切片高度。默認150
	 */
	public final static void cut3(String srcImageFile, String descDir, int destWidth, int destHeight) {
		try {
			if (destWidth <= 0)
				destWidth = 200; // 切片寬度
			if (destHeight <= 0)
				destHeight = 150; // 切片高度
			// 讀取源圖像
			BufferedImage bi = ImageIO.read(new File(srcImageFile));
			int srcWidth = bi.getHeight(); // 源圖寬度
			int srcHeight = bi.getWidth(); // 源圖高度
			if (srcWidth > destWidth && srcHeight > destHeight) {
				Image img;
				ImageFilter cropFilter;
				Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
				int cols = 0; // 切片橫向數量
				int rows = 0; // 切片縱向數量
				// 計算切片的橫向和縱向數量
				if (srcWidth % destWidth == 0) {
					cols = srcWidth / destWidth;
				} else {
					cols = (int) Math.floor(srcWidth / destWidth) + 1;
				}
				if (srcHeight % destHeight == 0) {
					rows = srcHeight / destHeight;
				} else {
					rows = (int) Math.floor(srcHeight / destHeight) + 1;
				}
				// 循環建立切片
				// 改進的想法:是否可用多線程加快切割速度
				for (int i = 0; i < rows; i++) {
					for (int j = 0; j < cols; j++) {
						// 四個參數分別爲圖像起點座標和寬高
						// 即: CropImageFilter(int x,int y,int width,int height)
						cropFilter = new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight);
						img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
						BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
						Graphics g = tag.getGraphics();
						g.drawImage(img, 0, 0, null); // 繪製縮小後的圖
						g.dispose();
						// 輸出爲文件
						ImageIO.write(tag, "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg"));
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 圖像類型轉換:GIF->JPG、GIF->PNG、PNG->JPG、PNG->GIF(X)、BMP->PNG
	 * 
	 * @param srcImageFile
	 *            源圖像地址
	 * @param formatName
	 *            包含格式非正式名稱的 String:如JPG、JPEG、GIF等
	 * @param destImageFile
	 *            目標圖像地址
	 */
	public final static void convert(String srcImageFile, String formatName, String destImageFile) {
		try {
			File f = new File(srcImageFile);
			f.canRead();
			f.canWrite();
			BufferedImage src = ImageIO.read(f);
			ImageIO.write(src, formatName, new File(destImageFile));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 彩色轉爲黑白
	 * 
	 * @param srcImageFile
	 *            源圖像地址
	 * @param destImageFile
	 *            目標圖像地址
	 */
	public final static void gray(String srcImageFile, String destImageFile) {
		try {
			BufferedImage src = ImageIO.read(new File(srcImageFile));
			ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
			ColorConvertOp op = new ColorConvertOp(cs, null);
			src = op.filter(src, null);
			ImageIO.write(src, "JPEG", new File(destImageFile));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 給圖片添加文字水印
	 * 
	 * @param pressText
	 *            水印文字
	 * @param srcImageFile
	 *            源圖像地址
	 * @param destImageFile
	 *            目標圖像地址
	 * @param fontName
	 *            水印的字體名稱
	 * @param fontStyle
	 *            水印的字體樣式
	 * @param color
	 *            水印的字體顏色
	 * @param fontSize
	 *            水印的字體大小
	 * @param x
	 *            修正值
	 * @param y
	 *            修正值
	 * @param sh
	 *            行高
	 * @param row
	 *            在幾行中間打水印
	 * @param alpha
	 *            透明度:alpha 必須是範圍 [0.0, 1.0] 之內(包含邊界值)的一個浮點數字
	 */
	public final static void pressText(String pressText, String srcImageFile, String destImageFile, String fontName, int fontStyle, Color color, int fontSize, int x, int y, float alpha, int sh, int row) {
		try {
			File img = new File(srcImageFile);
			Image src = ImageIO.read(img);
			int width = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			Graphics2D g = image.createGraphics();
			g.drawImage(src, 0, 0, width, height, null);
			g.setColor(color);
			if ((getLength(pressText) * fontSize) > width) {
				fontSize = width / (getLength(pressText) + 1);
			}
			g.setFont(new Font(fontName, fontStyle, fontSize));
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
			// 在指定座標繪製水印文字
			int a = (int) Math.ceil((height - 52) / (sh * row));
			if (a > 1) {
				for (int i = 0; i < a; i++) {
					// 在指定座標繪製水印文字
					g.drawString(pressText, (width - (getLength(pressText) * fontSize)) / 2 + x, (sh * row + fontSize) / 2 + 52 + sh * row * i + y);
				}
			} else {
				g.drawString(pressText, (width - ((getLength(pressText) + 1) * fontSize)) / 2 + x, (height + fontSize) / 2 - 20 + y);
			}
			g.dispose();
			ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile));// 輸出到文件流
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 給圖片添加文字水印
	 * 
	 * @param pressText
	 *            水印文字
	 * @param srcImageFile
	 *            源圖像地址
	 * @param destImageFile
	 *            目標圖像地址
	 * @param fontName
	 *            字體名稱
	 * @param fontStyle
	 *            字體樣式
	 * @param color
	 *            字體顏色
	 * @param fontSize
	 *            字體大小
	 * @param x
	 *            修正值
	 * @param y
	 *            修正值
	 * @param alpha
	 *            透明度:alpha 必須是範圍 [0.0, 1.0] 之內(包含邊界值)的一個浮點數字
	 */
	public final static void pressText2(String pressText, String srcImageFile, String destImageFile, String fontName, int fontStyle, Color color, int fontSize, int x, int y, float alpha) {
		try {
			File img = new File(srcImageFile);
			Image src = ImageIO.read(img);
			int width = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			Graphics2D g = image.createGraphics();
			g.drawImage(src, 0, 0, width, height, null);
			g.setColor(color);
			g.setFont(new Font(fontName, fontStyle, fontSize));
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
			// 在指定座標繪製水印文字
			g.drawString(pressText, (width - (getLength(pressText) * fontSize)) / 2 + x, (height - fontSize) / 2 + y);
			g.dispose();
			ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 給圖片添加圖片水印
	 * 
	 * @param pressImg
	 *            水印圖片
	 * @param srcImageFile
	 *            源圖像地址
	 * @param destImageFile
	 *            目標圖像地址
	 * @param x
	 *            修正值。 默認在中間
	 * @param y
	 *            修正值。 默認在中間
	 * @param alpha
	 *            透明度:alpha 必須是範圍 [0.0, 1.0] 之內(包含邊界值)的一個浮點數字
	 */
	public final static void pressImage(String pressImg, String srcImageFile, String destImageFile, int x, int y, float alpha) {
		try {
			File img = new File(srcImageFile);
			Image src = ImageIO.read(img);
			int wideth = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
			Graphics2D g = image.createGraphics();
			g.drawImage(src, 0, 0, wideth, height, null);
			// 水印文件
			Image src_biao = ImageIO.read(new File(pressImg));
			int wideth_biao = src_biao.getWidth(null);
			int height_biao = src_biao.getHeight(null);
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
			g.drawImage(src_biao, (wideth - wideth_biao) / 2, (height - height_biao) / 2, wideth_biao, height_biao, null);
			// 水印文件結束
			g.dispose();
			ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 計算text的長度(一箇中文算兩個字符)
	 * 
	 * @param text
	 * @return
	 */
	public final static int getLength(String text) {
		int length = 0;
		for (int i = 0; i < text.length(); i++) {
			if (new String(text.charAt(i) + "").getBytes().length > 1) {
				length += 2;
			} else {
				length += 1;
			}
		}
		return length / 2;
	}

	/**
	 * 將Base64位編碼的圖片進行解碼,並保存到指定目錄
	 *
	 * @param base64
	 *            base64編碼的圖片信息
	 * @return
	 * @throws Exception
	 */
	public static String decodeBase64ToImage(String base64, String partPath, String imgName) throws Exception {
		BASE64Decoder decoder = new BASE64Decoder();
		String regEx = "^(data:image\\/(\\w+);base64,)";
		Pattern pattern = Pattern.compile(regEx);
		Matcher matcher = pattern.matcher(base64);
		base64 = matcher.replaceFirst("");
		byte[] decoderBytes = decoder.decodeBuffer(base64);
		for (int i = 0; i < decoderBytes.length; ++i) {
			if (decoderBytes[i] < 0) {// 調整異常數據
				decoderBytes[i] += 256;
			}
		}
		return FtpUtils.uploadFile(partPath, decoderBytes,imgName);
		
	}
}

ftp工具類:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import com.ouyeel.common.model.CustomException;

public class FtpUtils {

	/**
	 * 屬性集
	 */
	private static Property property = null;

	/**
	 * FTP 登錄用戶名
	 */
	private static String userName;

	/**
	 * FTP 登錄密碼
	 */
	private static String passWord;

	/**
	 * FTP 服務器地址IP地址
	 */
	private static String hostName;

	/**
	 * FTP 端口
	 */
	private static int port;

	/**
	 * 文件服務器路徑
	 */
	private static String path;

	/**
	 * 文件服務器訪問地址
	 */
	private static String header;

	/**
	 * 配置文件的路徑名
	 */
	private static String configFile = "application.properties";
	/**
	 * ftp文件下載的地址,例如:模板
	 */
	private static String tmstctpFilePath;

	/**
	 * 關閉連接-FTP方式
	 *
	 * @param ftp
	 *            FTPClient對象
	 * @return boolean
	 */
	public static boolean closeFTP(FTPClient ftp) {
		if (ftp.isConnected()) {
			try {
				ftp.disconnect();
				System.out.println("ftp已經關閉");
				return true;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	/**
	 * 上傳文件-FTP方式
	 *
	 * @param hostName
	 *            FTP服務器地址
	 * @param port
	 *            FTP服務器端口
	 * @param userName
	 *            FTP登錄用戶名
	 * @param passWord
	 *            FTP登錄密碼
	 * @param path
	 *            FTP服務器上傳地址
	 * @param fileName
	 *            文件名稱
	 * @param inputStream
	 *            輸入流
	 * @return boolean
	 * @throws Exception
	 */
	public static String uploadFile(String partPath, byte[] decoderBytes,String imgName) throws Exception {
		FTPClient ftp = new FTPClient();
		try {
			setArg(configFile);
			// 連接FTP服務器
			ftp.connect(hostName, port);
			// 下面三行代碼必須要,而且不能改變編碼格式,否則不能正確下載中文文件
			ftp.setControlEncoding("GBK");
			FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
			conf.setServerLanguageCode("zh");
			// 登錄ftp
			ftp.login(userName, passWord);
			if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
				ftp.disconnect();
				System.out.println("連接服務器失敗");
			}
			System.out.println("登陸服務器成功");
			String realPath = path + "/" + partPath;
			boolean changeWD = ftp.changeWorkingDirectory(realPath);// 轉移到指定FTP服務器目錄
			if (!changeWD) {
				if (!CreateDirecroty(realPath, ftp)) {
					throw new Exception("創建遠程文件夾失敗!");
				}
			}
			FTPFile[] fs = ftp.listFiles();// 得到目錄的相應文件列表
			String fileName = imgName;
			fileName = FtpUtils.changeName(fileName, fs);
			fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
			realPath = new String(realPath.getBytes("GBK"), "ISO-8859-1");
			// 轉到指定上傳目錄
			ftp.changeWorkingDirectory(realPath);
			// 將上傳文件存儲到指定目錄
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			// 如果缺省該句 傳輸txt正常 但圖片和其他格式的文件傳輸出現亂碼
			ftp.storeFile(fileName, new ByteArrayInputStream(decoderBytes));
			// 退出ftp
			ftp.logout();
			System.out.println("上傳成功。。。。。。");
			return header + realPath + fileName;
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			// 關閉ftp連接
			closeFTP(ftp);
		}
	}

	/**
	 * 判斷是否有重名文件
	 *
	 * @param fileName
	 * @param fs
	 * @return
	 */
	public static boolean isFileExist(String fileName, FTPFile[] fs) {
		for (int i = 0; i < fs.length; i++) {
			FTPFile ff = fs[i];
			if (ff.getName().equals(fileName)) {
				return true; // 如果存在返回 正確信號
			}
		}
		return false; // 如果不存在返回錯誤信號
	}

	/**
	 * 根據重名判斷的結果 生成新的文件的名稱
	 *
	 * @param fileName
	 * @param fs
	 * @return
	 */
	public static String changeName(String fileName, FTPFile[] fs) {
		int n = 0;
		// fileName = fileName.append(fileName);
		while (isFileExist(fileName.toString(), fs)) {
			n++;
			String a = "[" + n + "]";
			int b = fileName.lastIndexOf(".");// 最後一出現小數點的位置
			int c = fileName.lastIndexOf("[");// 最後一次"["出現的位置
			if (c < 0) {
				c = b;
			}
			StringBuffer name = new StringBuffer(fileName.substring(0, c));// 文件的名字
			StringBuffer suffix = new StringBuffer(fileName.substring(b + 1));// 後綴的名稱
			fileName = name.append(a) + "." + suffix;
		}
		return fileName.toString();
	}

	/**
	 * 遞歸創建遠程服務器目錄
	 *
	 * @param remote
	 *            遠程服務器文件絕對路徑
	 *
	 * @return 目錄創建是否成功
	 * @throws IOException
	 */
	public static boolean CreateDirecroty(String remote, FTPClient ftp) throws IOException {
		boolean success = true;
		String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
		// 如果遠程目錄不存在,則遞歸創建遠程服務器目錄
		if (!directory.equalsIgnoreCase("/") && !ftp.changeWorkingDirectory(new String(directory))) {

			int start = 0;
			int end = 0;
			if (directory.startsWith("/")) {
				start = 1;
			} else {
				start = 0;
			}
			end = directory.indexOf("/", start);
			while (true) {
				String subDirectory = new String(remote.substring(start, end));
				if (!ftp.changeWorkingDirectory(subDirectory)) {
					if (ftp.makeDirectory(subDirectory)) {
						ftp.changeWorkingDirectory(subDirectory);
					} else {
						System.out.println("創建目錄失敗");
						success = false;
						return success;
					}
				}
				start = end + 1;
				end = directory.indexOf("/", start);
				// 檢查所有目錄是否創建完畢
				if (end <= start) {
					break;
				}
			}
		}
		return success;
	}

	/**
	 * 
	 * @param configFile
	 */
	private static void setArg(String configFile) {
		property = new Property(configFile);
		try {
			userName = property.getValue("ciftpUserName");
			passWord = property.getValue("ciftpPassword");
			hostName = property.getValue("ciftpHost");
			path = property.getValue("ciftpPath");
			port = Integer.parseInt(property.getValue("ciftpPort"));
			header = property.getValue("ciftpHeader");
			tmstctpFilePath=property.getValue("tmstctpFilePath");
		} catch (Exception e1) {
			System.out.println("配置文件 【" + configFile + "】不存在!");
			e1.printStackTrace();
		}
	}
	/**
	 * 下載文件
	 * @param fileName
	 * @param response
	 * @return
	 * @throws IOException
	 */
	public static boolean downFile(String fileName,HttpServletResponse response){		
		boolean success = false;
		setArg(configFile);
		FTPClient ftp = new FTPClient();
		OutputStream outputStream=null;
		try {
			outputStream=response.getOutputStream();
			int reply;
			ftp.connect(hostName, port);
			// 下面三行代碼必須要,而且不能改變編碼格式
			ftp.setControlEncoding("GBK");
			FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
			conf.setServerLanguageCode("zh");
			// 如果採用默認端口,可以使用ftp.connect(url) 的方式直接連接FTP服務器
			ftp.login(userName, passWord);// 登錄
			ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
			reply = ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return success;
			}
			System.out.println("登陸成功。。。。");
			ftp.changeWorkingDirectory(tmstctpFilePath);// 轉移到FTP服務器目錄
			FTPFile[] fs = ftp.listFiles(); // 得到目錄的相應文件列
			for (int i = 0; i < fs.length; i++) {
				FTPFile ff = fs[i];
				if (ff.getName().equals(fileName)) {
					String filename = fileName;
					// 這個就就是彈出下載對話框的關鍵代碼
					response.setHeader("Content-disposition",
							"attachment;filename="+ URLEncoder.encode(filename, "utf-8"));
					// 將文件保存到輸出流outputStream中
					ftp.retrieveFile(new String(ff.getName().getBytes("GBK"),
							"ISO-8859-1"), outputStream);
					outputStream.flush();
					outputStream.close();
					success = true;
				}
			}
			ftp.logout();
		} catch (IOException e) {
			e.printStackTrace();
			throw new CustomException("下載文件出錯!");
		} finally {
			// 關閉ftp連接
			closeFTP(ftp);
		}
		return success;

	}

	// public static void main(String[] args) throws Exception {
	// String str =
	// "data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQ";
	// String regEx = "^(data:image\\/(\\w+);base64,)";
	// Pattern pattern = Pattern.compile(regEx);
	// Matcher matcher = pattern.matcher(str);
	// String s = matcher.replaceFirst("");
	// System.out.println(s);
	// }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章