package com.doing.utils;
import java.awt.*;
import java.awt.image.BufferedImage;
public class ImageRotate {
/**
* 旋转角度
* @param src 源图片
* @param angel 角度
* @return 目标图片
*/
public static BufferedImage rotate(Image src, int angel) {
int src_width = src.getWidth(null);
int src_height = src.getHeight(null);
// calculate the new image size
Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(
src_width, src_height)), angel);
BufferedImage res = null;
res = new BufferedImage(rect_des.width, rect_des.height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = res.createGraphics();
// transform(这里先平移、再旋转比较方便处理;绘图时会采用这些变化,绘图默认从画布的左上顶点开始绘画,源图片的左上顶点与画布左上顶点对齐,然后开始绘画,修改坐标原点后,绘画对应的画布起始点改变,起到平移的效果;然后旋转图片即可)
//平移(原理修改坐标系原点,绘图起点变了,起到了平移的效果,如果作用于旋转,则为旋转中心点)
g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);
//旋转(原理transalte(dx,dy)->rotate(radians)->transalte(-dx,-dy);修改坐标系原点后,旋转90度,然后再还原坐标系原点为(0,0),但是整个坐标系已经旋转了相应的度数 )
g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);
// //先旋转(以目标区域中心点为旋转中心点,源图片左上顶点对准目标区域中心点,然后旋转)
// g2.translate(rect_des.width/2,rect_des.height/ 2);
// g2.rotate(Math.toRadians(angel));
// //再平移(原点恢复到源图的左上顶点处(现在的右上顶点处),否则只能画出1/4)
// g2.translate(-src_width/2,-src_height/2);
g2.drawImage(src, null, null);
return res;
}
/**
* 计算转换后目标矩形的宽高
* @param src 源矩形
* @param angel 角度
* @return 目标矩形
*/
private static Rectangle CalcRotatedSize(Rectangle src, int angel) {
double cos = Math.abs(Math.cos(Math.toRadians(angel)));
double sin = Math.abs(Math.sin(Math.toRadians(angel)));
int des_width = (int)(src.width * cos) + (int)(src.height * sin);
int des_height = (int)(src.height * cos) + (int)(src.width * sin);
return new java.awt.Rectangle(new Dimension(des_width, des_height));
}
}
@Test
public void ImageRotateTest() throws IOException {
File file = new File("E:\\list\\14566-1.jpg");
//创建图片对象
BufferedImage originalImage = ImageIO.read(file);
//旋转图片
BufferedImage rotateImage = ImageRotate.rotate(originalImage, 0);
//裁剪图片
int x=822;
int y=1640;
int w=600;
int h=220;
BufferedImage cropImage = rotateImage.getSubimage(x, y, w, h);
ImageIO.write(cropImage, "jpg", new File("E:\\list\\14566-1_rotateImage.jpg"));
}
图片处理
增强光学字符识别
package com.doing.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class ImageBinarization {
public ByteArrayOutputStream convert(File file) throws IOException {
BufferedImage bi = ImageIO.read(file);
return getByteArrayOutputStream(bi);
}
private ByteArrayOutputStream getByteArrayOutputStream(BufferedImage bi) throws IOException {
// 获取当前图片的高,宽,ARGB
int h = bi.getHeight();
int w = bi.getWidth();
int rgb = bi.getRGB(0, 0);
int arr[][] = new int[w][h];
// 获取图片每一像素点的灰度值
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
// getRGB()返回默认的RGB颜色模型(十进制)
arr[i][j] = getImageRgb(bi.getRGB(i, j));//该点的灰度值
}
}
BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);// 构造一个类型为预定义图像类型之一的 BufferedImage,TYPE_BYTE_BINARY(表示一个不透明的以字节打包的 1、2 或 4 位图像。)
int FZ = 130;
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
if (getGray(arr, i, j, w, h) > FZ) {
int black = new Color(255, 255, 255).getRGB();
bufferedImage.setRGB(i, j, black);
} else {
int white = new Color(0, 0, 0).getRGB();
bufferedImage.setRGB(i, j, white);
}
}
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "jpg", bos);
return bos;
}
public ByteArrayOutputStream convert(InputStream in) throws IOException {
BufferedImage bi = ImageIO.read(in);
// 获取当前图片的高,宽,ARGB
return getByteArrayOutputStream(bi);
}
private int getImageRgb(int i) {
String argb = Integer.toHexString(i);// 将十进制的颜色值转为十六进制
// argb分别代表透明,红,绿,蓝 分别占16进制2位
int r = Integer.parseInt(argb.substring(2, 4), 16);//后面参数为使用进制
int g = Integer.parseInt(argb.substring(4, 6), 16);
int b = Integer.parseInt(argb.substring(6, 8), 16);
int result = (int) ((r + g + b) / 3);
return result;
}
//自己加周围8个灰度值再除以9,算出其相对灰度值
private int getGray(int gray[][], int x, int y, int w, int h) {
int rs = gray[x][y]
+ (x == 0 ? 255 : gray[x - 1][y])
+ (x == 0 || y == 0 ? 255 : gray[x - 1][y - 1])
+ (x == 0 || y == h - 1 ? 255 : gray[x - 1][y + 1])
+ (y == 0 ? 255 : gray[x][y - 1])
+ (y == h - 1 ? 255 : gray[x][y + 1])
+ (x == w - 1 ? 255 : gray[x + 1][y])
+ (x == w - 1 || y == 0 ? 255 : gray[x + 1][y - 1])
+ (x == w - 1 || y == h - 1 ? 255 : gray[x + 1][y + 1]);
return rs / 9;
}
}