因爲幾乎用到的都是工具類,且不常用,所以就不做分析,用時查即可。
目錄
1.圖片操作
package basic;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
public class ImageTest {
public static void main(String[] args) throws Exception {
readAndWrite();//讀取圖片的長寬像素
readComparison();//比較兩種打開圖片的方法速度
cropImage("c:/temp/ecnu.jpg", "c:/temp/shida.jpg", 750, 250, 700, 300, "jpg", "jpg");//截取圖片
combineImagesHorizontally("c:/temp/ecnu.jpg","c:/temp/ecnu.jpg","jpg", "c:/temp/ecnu2.jpg");//橫向拼接圖片
combineImagesVertically("c:/temp/ecnu.jpg","c:/temp/ecnu.jpg","jpg", "c:/temp/ecnu3.jpg");//縱向拼接圖片
}
public static void readAndWrite() throws Exception {
BufferedImage image = ImageIO.read(new File("c:/temp/ecnu.jpg"));//讀取圖像文件
System.out.println("Height: " + image.getHeight()); // 高度像素
System.out.println("Width: " + image.getWidth()); // 寬度像素
ImageIO.write(image, "png", new File("c:/temp/ecnu.png"));//格式轉換
}
public static void readComparison() throws Exception {
System.out.println("===========加載速度測試==============");
// ImageIO需要測試圖片的類型,加載合適的ImageReader來讀取圖片,耗時更長
long startTime = System.nanoTime();
BufferedImage image = ImageIO.read(new File("c:/temp/ecnu.jpg"));
System.out.println("Height: " + image.getHeight()); // 高度像素
System.out.println("Width: " + image.getWidth()); // 寬度像素
long endTime = System.nanoTime();
System.out.println((endTime - startTime) / 1000000.0 + "毫秒");
// 指定用jpg Reader來加載,速度會加快
startTime = System.nanoTime();
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("jpg");
ImageReader reader = (ImageReader) readers.next();
System.out.println(reader.getClass().getName());
ImageInputStream iis = ImageIO.createImageInputStream(new File("c:/temp/ecnu.jpg"));
reader.setInput(iis, true);
System.out.println("Height:" + reader.getHeight(0));
System.out.println("Width:" + reader.getWidth(0));
endTime = System.nanoTime();
System.out.println((endTime - startTime) / 1000000.0 + "毫秒");
}
/**
* cropImage 將原始圖片文件切割一個矩形,並輸出到目標圖片文件
* @param fromPath 原始圖片
* @param toPath 目標圖片
* @param x 座標起點x
* @param y 座標起點y
* @param width 矩形寬度
* @param height 矩形高度
* @param readImageFormat 原始文件格式
* @param writeImageFormat 目標文件格式
* @throws Exception
*/
public static void cropImage(String fromPath, String toPath, int x, int y, int width, int height, String readImageFormat,
String writeImageFormat) throws Exception {//截取圖片
FileInputStream fis = null;
ImageInputStream iis = null;
try {
// 讀取原始圖片文件
fis = new FileInputStream(fromPath);
Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(readImageFormat);
ImageReader reader = it.next();
iis = ImageIO.createImageInputStream(fis);
reader.setInput(iis, true);
// 定義一個矩形 並放入切割參數中
ImageReadParam param = reader.getDefaultReadParam();
Rectangle rect = new Rectangle(x, y, width, height);//起始點位置,加寬高
param.setSourceRegion(rect);
//從源文件讀取一個矩形大小的圖像
BufferedImage bi = reader.read(0, param);
//寫入到目標文件
ImageIO.write(bi, writeImageFormat, new File(toPath));
} finally {
fis.close();
iis.close();
}
}
/**
* 橫向拼接兩張圖片,並寫入到目標文件
* 拼接的本質,就是申請一個大的新空間,然後將原始的圖片像素點拷貝到新空間,最後保存
* @param firstPath 第一張圖片的路徑
* @param secondPath 第二張圖片的路徑
* @param imageFormat 拼接生成圖片的格式
* @param toPath 目標圖片的路徑
*/
public static void combineImagesHorizontally(String firstPath, String secondPath,String imageFormat, String toPath){
try {
//讀取第一張圖片
File first = new File(firstPath);
BufferedImage imageOne = ImageIO.read(first);
int width1 = imageOne.getWidth();//圖片寬度
int height1 = imageOne.getHeight();//圖片高度
//從第一張圖片中讀取RGB
int[] firstRGB = new int[width1*height1];
firstRGB = imageOne.getRGB(0,0,width1,height1,firstRGB,0,width1);
//對第二張圖片做同樣的處理
File second = new File(secondPath);
BufferedImage imageTwo = ImageIO.read(second);
int width2 = imageTwo.getWidth();
int height2 = imageTwo.getHeight();
int[] secondRGB = new int[width2*height2];
secondRGB = imageTwo.getRGB(0,0,width2,height2,secondRGB,0,width2);
//生成新圖片
int height3 = (height1>height2)?height1:height2; //挑選高度大的,作爲目標文件的高度
int width3 = width1 + width2; //寬度,兩張圖片相加
BufferedImage imageNew = new BufferedImage(width3,height3,BufferedImage.TYPE_INT_RGB);
//設置左半部分的RGB 從(0,0) 開始
imageNew.setRGB(0,0,width1,height1,firstRGB,0,width1);
//設置右半部分的RGB 從(width1, 0) 開始
imageNew.setRGB(width1,0,width2,height2,secondRGB,0,width2);
//保存圖片
ImageIO.write(imageNew, imageFormat, new File(toPath));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 縱向拼接圖片(兩張)
* 拼接的本質,就是申請一個大的新空間,然後將原始的圖片像素點拷貝到新空間,最後保存
* @param firstPath 讀取的第一張圖片
* @param secondPath 讀取的第二張圖片
* @param imageFormat 圖片寫入格式
* @param toPath 圖片寫入路徑
*/
public static void combineImagesVertically(String firstPath, String secondPath,String imageFormat, String toPath){
try {
//讀取第一張圖片
File first = new File(firstPath);
BufferedImage imageOne = ImageIO.read(first);
int width1 = imageOne.getWidth();//圖片寬度
int height1 = imageOne.getHeight();//圖片高度
//從圖片中讀取RGB
int[] firstRGB = new int[width1*height1];
firstRGB = imageOne.getRGB(0,0,width1,height1,firstRGB,0,width1);
//對第二張圖片做相同的處理
File second = new File(secondPath);
BufferedImage imageTwo = ImageIO.read(second);
int width2 = imageTwo.getWidth();
int height2 = imageTwo.getHeight();
int[] secondRGB = new int[width2*height2];
secondRGB = imageTwo.getRGB(0,0,width2,height2,secondRGB,0,width2);
//生成新圖片
int width3 = (width1>width2)?width1:width2; //挑選寬度大的,作爲目標文件的寬度
int height3 = height1+height2; //高度,兩張圖片相加
BufferedImage imageNew = new BufferedImage(width3,height3,BufferedImage.TYPE_INT_RGB);
//設置上半部分的RGB 從(0,0) 開始
imageNew.setRGB(0,0,width1,height1,firstRGB,0,width1);
//設置下半部分的RGB 從(0, height1) 開始
imageNew.setRGB(0,height1,width2,height2,secondRGB,0,width2);
//保存圖片
ImageIO.write(imageNew, imageFormat, new File(toPath));
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.驗證碼生成
package code;
/*
* 產生驗證碼
*/
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
public class ValidateCodeTest {
//沒有1 I L 0 o
static char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9' };
static int charNum = codeSequence.length;
public static void main(String[] a) throws IOException
{
generateCode("c:/temp/code.jpg");
}
public static void generateCode(String filePath) throws IOException {
// 首先定義驗證碼圖片框
int width = 80; // 驗證碼圖片的寬度
int height = 32; // 驗證碼圖片的高度
BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//定義圖片上的圖形和干擾線
Graphics2D gd = buffImg.createGraphics();
gd.setColor(Color.LIGHT_GRAY); // 將圖像填充爲淺灰色
gd.fillRect(0, 0, width, height);
gd.setColor(Color.BLACK); // 畫邊框。
gd.drawRect(0, 0, width - 1, height - 1);
// 隨機產生16條灰色干擾線,使圖像中的認證碼不易識別
gd.setColor(Color.gray);
// 創建一個隨機數生成器類 用於隨機產生干擾線
Random random = new Random();
for (int i = 0; i < 16; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
gd.drawLine(x, y, x + xl, y + yl);
}
//計算字的位置座標
int codeCount = 4; // 字符個數
int fontHeight; // 字體高度
int codeX; // 第一個字符的x座標,因爲後面的字符座標依次遞增,所以它們的x軸值是codeX的倍數
int codeY; // 驗證字符的y座標,因爲並排所以值一樣
// width-4 除去左右多餘的位置,使驗證碼更加集中顯示,減得越多越集中。
// codeCount+1 //等比分配顯示的寬度,包括左右兩邊的空格
codeX = (width - 4) / (codeCount + 1); //第一個字母的起始位置
fontHeight = height - 10; // height - 10 高度中間區域顯示驗證碼
codeY = height - 7;
// 創建字體,字體的大小應該根據圖片的高度來定。
Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
gd.setFont(font);
// 隨機產生codeCount數字的驗證碼。
for (int i = 0; i < codeCount; i++) {
// 每次隨機拿一個字母,賦予隨機的顏色
String strRand = String.valueOf(codeSequence[random.nextInt(charNum)]);
int red = random.nextInt(255);
int green = random.nextInt(255);
int blue = random.nextInt(255);
gd.setColor(new Color(red,green,blue));
//把字放到圖片上!!!
gd.drawString(strRand, (i + 1) * codeX, codeY);
}
ImageIO.write(buffImg, "jpg", new File(filePath));
}
}
3.統計圖生成:
這個用到了第三方庫jfreechart
需要依賴
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.19</version>
</dependency>
package charts;
/*
* 設計柱狀圖用到了第三方庫JFreeChart
*/
import java.awt.Font;
import java.io.File;
import java.io.IOException;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
public class JFreeChartTest {
public static void main(String[] args) {
writeBar("c:/temp/bar.jpg"); // 柱狀圖
writePie("c:/temp/pie.jpg"); // 餅圖
writeLine("c:/temp/line.jpg");// 折線圖
}
public static StandardChartTheme getChineseTheme()
{
StandardChartTheme chineseTheme = new StandardChartTheme("CN");
chineseTheme.setExtraLargeFont(new Font("隸書", Font.BOLD, 20));
chineseTheme.setRegularFont(new Font("宋書", Font.PLAIN, 15));
chineseTheme.setLargeFont(new Font("宋書", Font.PLAIN, 15));
return chineseTheme;
}
public static void writeBar(String fileName) {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(11, "", "第一季度");
dataset.addValue(41, "", "第二季度");
dataset.addValue(51, "", "第三季度");
dataset.addValue(4, "", "第四季度");
// PlotOrientation.HORIZONTAL橫向 PlotOrientation.VERTICAL 豎向
// 引入中文主題樣式
ChartFactory.setChartTheme(getChineseTheme());
JFreeChart chart = ChartFactory.createBarChart3D("柱狀圖", "2018年", "產品總量", dataset, PlotOrientation.VERTICAL,
false, false, false);
try {
ChartUtilities.saveChartAsJPEG(new File(fileName), chart, 600, 300);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writePie(String fileName) {
DefaultPieDataset pds = new DefaultPieDataset();
pds.setValue("C人數", 100);
pds.setValue("C++人數", 200);
pds.setValue("Java人數", 300);
try {
ChartFactory.setChartTheme(getChineseTheme());
JFreeChart chart = ChartFactory.createPieChart("餅圖", pds);
ChartUtilities.saveChartAsJPEG(new File(fileName), chart, 600, 300);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void writeLine(String fileName) {
DefaultCategoryDataset lines = new DefaultCategoryDataset();
//第一條線
lines.addValue(100, "Java核心技術", "1月");
lines.addValue(200, "Java核心技術", "2月");
lines.addValue(400, "Java核心技術", "3月");
lines.addValue(500, "Java核心技術", "4月");
//第二條線
lines.addValue(100, "Java核心技術(進階)", "1月");
lines.addValue(400, "Java核心技術(進階)", "2月");
lines.addValue(900, "Java核心技術(進階)", "3月");
try {
ChartFactory.setChartTheme(getChineseTheme());
JFreeChart chart = ChartFactory.createLineChart("折線圖", "時間", "人數", lines);
ChartUtilities.saveChartAsJPEG(new File(fileName), chart, 600, 300);
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.一/二維碼的生成與解析
用到了zxing的第三方庫或barcode4j第三方庫
pox.xml文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>MOOC16-05</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.barcode4j/barcode4j -->
<dependency>
<groupId>net.sf.barcode4j</groupId>
<artifactId>barcode4j</artifactId>
<version>2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.avalon.framework/avalon-framework-api -->
<dependency>
<groupId>org.apache.avalon.framework</groupId>
<artifactId>avalon-framework-api</artifactId>
<version>4.3.1</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</project>
4.1一維碼
package zxing;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
public class BarCodeTest {
/**
* generateCode 根據code生成相應的一維碼
* @param file 一維碼目標文件
* @param code 一維碼內容
* @param width 圖片寬度
* @param height 圖片高度
*/
public static void generateCode(File file, String code, int width, int height) {
//定義位圖矩陣BitMatrix
BitMatrix matrix = null;
try {
// 使用code_128格式進行編碼生成100*25的條形碼
MultiFormatWriter writer = new MultiFormatWriter();
matrix = writer.encode(code,BarcodeFormat.CODE_128, width, height, null);
//matrix = writer.encode(code,BarcodeFormat.EAN_13, width, height, null);
} catch (WriterException e) {
e.printStackTrace();
}
//將位圖矩陣BitMatrix保存爲圖片
try (FileOutputStream outStream = new FileOutputStream(file)) {
ImageIO.write(MatrixToImageWriter.toBufferedImage(matrix), "png",
outStream);
outStream.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* readCode 讀取一張一維碼圖片
* @param file 一維碼圖片名字
*/
public static void readCode(File file){
try {
BufferedImage image = ImageIO.read(file);
if (image == null) {
return;
}
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "GBK");
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
Result result = new MultiFormatReader().decode(bitmap, hints);
System.out.println("條形碼內容: "+result.getText());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
//generateCode(new File("1dcode.png"), "123456789012", 500, 250);//產生一維碼
readCode(new File("1dcode.png"));//讀取一維碼
}
}
4.2二維碼
package zxing;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
public class QRCodeTest {
/*
* 定義二維碼的寬高
*/
private static int WIDTH = 300;
private static int HEIGHT = 300;
private static String FORMAT = "png";//二維碼格式
//生成二維碼
public static void generateQRCode(File file, String content) {
//定義二維碼參數
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");//設置編碼
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//設置容錯等級
hints.put(EncodeHintType.MARGIN, 2);//設置邊距默認是5
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
Path path = file.toPath();
MatrixToImageWriter.writeToPath(bitMatrix, FORMAT, path);//寫到指定路徑下
} catch (Exception e) {
e.printStackTrace();
}
}
//讀取二維碼
public static void readQrCode(File file) {
MultiFormatReader reader = new MultiFormatReader();
try {
BufferedImage image = ImageIO.read(file);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image)));
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");//設置編碼
Result result = reader.decode(binaryBitmap, hints);
System.out.println("解析結果:" + result.toString());
System.out.println("二維碼格式:" + result.getBarcodeFormat());
System.out.println("二維碼文本內容:" + result.getText());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
generateQRCode(new File("2dcode.png"), "https://www.baidu.com");
readQrCode(new File("2dcode.png"));
//readQrCode(new File("2dcode.jpg"));
}
}
4.3補充barcode4j解析一/二維碼
package barcode4j;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import org.krysalis.barcode4j.impl.code39.Code39Bean;
import org.krysalis.barcode4j.impl.upcean.EAN13Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.UnitConv;
public class BarCodeTest {
public static void main(String[] args) {
String msg = "123456789012";
String path = "1dcode.png";
generateFile(msg, path);
}
public static void generateFile(String msg, String path) {
File file = new File(path);
try {
Code39Bean bean = new Code39Bean();
//EAN13Bean bean = new EAN13Bean();
// dpi精度
final int dpi = 150;
// module寬度
//bean.setModuleWidth(0.2);
final double width = UnitConv.in2mm(2.0f / dpi);
bean.setWideFactor(3);
bean.setModuleWidth(width);
bean.doQuietZone(false);
String format = "image/png";
// 輸出到流
BitmapCanvasProvider canvas = new BitmapCanvasProvider(new FileOutputStream(file), format, dpi,
BufferedImage.TYPE_BYTE_BINARY, false, 0);
// 生成條形碼
bean.generateBarcode(canvas, msg);
// 結束繪製
canvas.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package barcode4j;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import org.krysalis.barcode4j.impl.code39.Code39Bean;
import org.krysalis.barcode4j.impl.upcean.EAN13Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.UnitConv;
public class BarCodeTest {
public static void main(String[] args) {
String msg = "123456789012";
String path = "1dcode.png";
generateFile(msg, path);
}
public static void generateFile(String msg, String path) {
File file = new File(path);
try {
Code39Bean bean = new Code39Bean();
//EAN13Bean bean = new EAN13Bean();
// dpi精度
final int dpi = 150;
// module寬度
//bean.setModuleWidth(0.2);
final double width = UnitConv.in2mm(2.0f / dpi);
bean.setWideFactor(3);
bean.setModuleWidth(width);
bean.doQuietZone(false);
String format = "image/png";
// 輸出到流
BitmapCanvasProvider canvas = new BitmapCanvasProvider(new FileOutputStream(file), format, dpi,
BufferedImage.TYPE_BYTE_BINARY, false, 0);
// 生成條形碼
bean.generateBarcode(canvas, msg);
// 結束繪製
canvas.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}
5.docx文件操作
6.表格文件操作
7.pdf文件操作
5.6.7的代碼示例具體見本文鏈接的代碼資源文件,根據示例代碼可懂
參考中國大學mooc《Java核心技術》