java截取图片截图画框
目录
java截取图片截图画框
java图片截图
前言:上文中提到了图片的合成,这篇文章中介绍的是图片的截图。
需求:一张图片用鼠标画框,然后截图该图片。并在截图的框框划线标识。
图片合成:
如示例图:
核心代码块
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageInputStream;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
public class CutImgToByteTest {
private static Logger log = LoggerFactory.getLogger(CutImgToByteTest.class);
/**
*
* @param imgeByte 要截取图片的字节数组
* @param local 画框的坐标
* @param width 要截取图片的宽度(可从图片字节数组中获取)
* @param height 要截取图片的高度(可从图片字节数组中获取)
* @param picType 要截取图片的格式
* @return 截取后的图片的字节数组
*/
public static byte[] getCutImageToByte(byte[] imgeByte, JSONObject local, int width, int height, String picType) {
if (imgeByte != null && imgeByte.length > 0) {
ImageInputStream iis = null;
byte[] cutImgbytes = null;
try {
// ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
String types = Arrays.toString(ImageIO.getReaderFormatNames()).replace("]", ",");
if (picType == null || types.toLowerCase().indexOf(picType.toLowerCase() + ",") < 0) {
log.error("Sorry, the image suffix is illegal. the standard image suffix is {}." + types);
return null;
}
ByteArrayInputStream bais = new ByteArrayInputStream(imgeByte);
iis = ImageIO.createImageInputStream(bais);
// 获取 截图的w,h,x,y值
int subHeight = 5;
double dw = local.getDouble("w");
double dh = local.getDouble("h");
double dx = local.getDouble("x");
double dy = local.getDouble("y");
// 计算出 截图转换的X,Y,Width,Height
Rectangle rct = new Rectangle();
rct.setRect(width * dx, height * dy, width * dw, height * dh);
Rectangle curtRct = new Rectangle(0, rct.y - subHeight, width,rct.height + subHeight * 2);// 画矩形框
checkRectangle(curtRct, height, width);
Rectangle fillRect = new Rectangle(rct.x, subHeight, rct.width, rct.height);// 画矩形
checkRectangle(fillRect, curtRct.height, curtRct.width);
ImageReader reader = ImageIO.getImageReadersBySuffix(picType).next();
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
param.setSourceRegion(curtRct);
BufferedImage bi = reader.read(0, param);
Graphics2D graphics = (Graphics2D) bi.getGraphics();
graphics.setColor(new Color(0, 87, 167));
float alpha = 0.1f; // 透明度
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
graphics.fillRect(fillRect.x, fillRect.y, fillRect.width, fillRect.height);
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));
graphics.setStroke(new BasicStroke(5));
graphics.drawRoundRect(fillRect.x, subHeight, fillRect.width, fillRect.height, 0, 0);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, picType, baos);
graphics.dispose();// 释放资源
cutImgbytes = baos.toByteArray();
System.out.println("===截图成功===");
} catch (Exception e) {
System.out.println("===截图失败===");
e.printStackTrace();
} finally {
try {
if (iis != null) {
iis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return cutImgbytes;
} else {
log.warn("the src image is not exist.");
}
return null;
}
private static void checkRectangle(Rectangle fillRect, int height, int width) {
int subWidth = 5;
int subHeight = 5;
if (fillRect.x <= subWidth || (fillRect.x + fillRect.width + subWidth * 2) >= width) {// 超出边界
if (fillRect.x <= subWidth) {
fillRect.x = subWidth;
}
if ((fillRect.x + fillRect.width + subWidth * 2) >= width) {
fillRect.width = Math.min((fillRect.x + fillRect.width + subWidth * 2), width)
- (fillRect.x + subWidth * 2);// 超出边界判断
if (fillRect.width == width) {
fillRect.width -= subWidth;
}
}
}
if (fillRect.y <= subHeight || (fillRect.y + fillRect.height + subHeight * 2) >= height) {// 超出边界
if (fillRect.y <= subHeight) {
fillRect.y = subHeight;
}
if ((fillRect.y + fillRect.height + subHeight * 2) >= height) {
fillRect.height = Math.min((fillRect.y + fillRect.height + subHeight * 2), height)
- (fillRect.y + subHeight * 2);// 超出边界判断
if (fillRect.height == height) {
fillRect.height -= subHeight;
}
}
}
}
public static void main(String[] args) throws IOException {
// 图片截图
File file = new File("C:/Users/Administrator/Desktop/001/NO1.jpg");
byte[] imgeByte = FileUtils.readFileToByteArray(file);
/**
* 图片中的坐标值:x=该框的左上角定点距离图片的左边距离/整个图片的宽度得到的值
* 其余的亦同
*/
JSONObject local = new JSONObject();
local.put("x", 0.14021421616358326);
local.put("y", 0.1348870056497175);
local.put("w", 0.7049659201557936);
local.put("h", 0.13206214689265536);
Integer width = 1664;
Integer height = 2295;
String picType = "jpg";
byte[] cutImageToByte = getCutImageToByte(imgeByte, local, width, height, picType);
// 输出截图路径
File outFile = new File("C:/Users/Administrator/Desktop/001/截图.jpg");
FileImageOutputStream imageOutput = new FileImageOutputStream(outFile);
imageOutput.write(cutImageToByte, 0, cutImageToByte.length);
imageOutput.close();
System.out.println("====截图ok====");
}
}
写的不是很完整,防止备忘。
如有其它优化的地方,希望大家多多指教留言。