因为几乎用到的都是工具类,且不常用,所以就不做分析,用时查即可。
目录
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核心技术》