This commit is contained in:
Looly 2024-03-28 21:57:41 +08:00
parent eaed0bb932
commit 436b9199ef
10 changed files with 523 additions and 307 deletions

View File

@ -34,7 +34,7 @@ public class DesktopUtil {
*
* @return {@link Desktop}
*/
public static Desktop getDsktop() {
public static Desktop getDesktop() {
return Desktop.getDesktop();
}
@ -54,9 +54,9 @@ public class DesktopUtil {
* @since 4.6.3
*/
public static void browse(final URI uri) {
final Desktop dsktop = getDsktop();
final Desktop desktop = getDesktop();
try {
dsktop.browse(uri);
desktop.browse(uri);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
@ -68,9 +68,9 @@ public class DesktopUtil {
* @param file URL地址
*/
public static void open(final File file) {
final Desktop dsktop = getDsktop();
final Desktop desktop = getDesktop();
try {
dsktop.open(file);
desktop.open(file);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
@ -82,9 +82,9 @@ public class DesktopUtil {
* @param file 文件
*/
public static void edit(final File file) {
final Desktop dsktop = getDsktop();
final Desktop desktop = getDesktop();
try {
dsktop.edit(file);
desktop.edit(file);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
@ -96,9 +96,9 @@ public class DesktopUtil {
* @param file 文件
*/
public static void print(final File file) {
final Desktop dsktop = getDsktop();
final Desktop desktop = getDesktop();
try {
dsktop.print(file);
desktop.print(file);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
@ -110,9 +110,9 @@ public class DesktopUtil {
* @param mailAddress 邮件地址
*/
public static void mail(final String mailAddress) {
final Desktop dsktop = getDsktop();
final Desktop desktop = getDesktop();
try {
dsktop.mail(UrlUtil.toURI(mailAddress));
desktop.mail(UrlUtil.toURI(mailAddress));
} catch (final IOException e) {
throw new IORuntimeException(e);
}

View File

@ -201,7 +201,13 @@ public class RobotUtil {
* @return 写出到的文件
*/
public static File captureScreen(final File outFile) {
ImgUtil.write(captureScreen(), outFile);
BufferedImage image = null;
try{
image = captureScreen();
ImgUtil.write(image, outFile);
} finally {
ImgUtil.flush(image);
}
return outFile;
}

View File

@ -112,7 +112,15 @@ public abstract class AbstractCaptcha implements ICaptcha {
generateCode();
final ByteArrayOutputStream out = new ByteArrayOutputStream();
ImgUtil.writePng(createImage(this.code), out);
Image image = null;
try{
image = createImage(this.code);
ImgUtil.writePng(image, out);
} finally {
ImgUtil.flush(image);
}
this.imageBytes = out.toByteArray();
}
@ -189,7 +197,8 @@ public abstract class AbstractCaptcha implements ICaptcha {
}
/**
* 获取验证码图
* 获取验证码图<br>
* 注意返回的{@link BufferedImage}使用完毕后需要调用{@link BufferedImage#flush()}释放资源
*
* @return 验证码图
*/

View File

@ -12,9 +12,10 @@
package org.dromara.hutool.swing.img;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.io.file.FileTypeUtil;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.swing.img.color.ColorUtil;
@ -33,9 +34,7 @@ import java.util.List;
import java.util.Map;
/**
* <p>图片背景识别处理背景替换背景设置为矢量图</p>
* <p>根据一定规则算出图片背景色的RGB值进行替换</p>
* <p>2020-05-21 16:36</p>
* 图片背景识别处理背景替换背景设置为矢量图根据一定规则算出图片背景色的RGB值进行替换
*
* @author Dai Yuanchuan
**/
@ -45,7 +44,7 @@ public class BackgroundRemoval {
* 目前暂时支持的图片类型数组
* 其他格式的不保证结果
*/
public static String[] IMAGES_TYPE = {"jpg", "png"};
public static String[] IMAGES_TYPE = {ImgUtil.IMAGE_TYPE_JPG, ImgUtil.IMAGE_TYPE_JPEG, ImgUtil.IMAGE_TYPE_PNG};
/**
* 背景移除
@ -59,10 +58,9 @@ public class BackgroundRemoval {
* @param inputPath 要处理图片的路径
* @param outputPath 输出图片的路径
* @param tolerance 容差值[根据图片的主题色,加入容差值,值的范围在0~255之间]
* @return 返回处理结果 true:图片处理完成 false:图片处理失败
*/
public static boolean backgroundRemoval(final String inputPath, final String outputPath, final int tolerance) {
return backgroundRemoval(new File(inputPath), new File(outputPath), tolerance);
public static void backgroundRemoval(final String inputPath, final String outputPath, final int tolerance) {
backgroundRemoval(new File(inputPath), new File(outputPath), tolerance);
}
/**
@ -77,10 +75,9 @@ public class BackgroundRemoval {
* @param input 需要进行操作的图片
* @param output 最后输出的文件
* @param tolerance 容差值[根据图片的主题色,加入容差值,值的取值范围在0~255之间]
* @return 返回处理结果 true:图片处理完成 false:图片处理失败
*/
public static boolean backgroundRemoval(final File input, final File output, final int tolerance) {
return backgroundRemoval(input, output, null, tolerance);
public static void backgroundRemoval(final File input, final File output, final int tolerance) {
backgroundRemoval(input, output, null, tolerance);
}
/**
@ -93,22 +90,20 @@ public class BackgroundRemoval {
* 发现相同则将颜色不透明度设置为0,使颜色完全透明.
*
* @param input 需要进行操作的图片
* @param output 最后输出的文件
* @param output 最后输出的文件必须为.png
* @param override 指定替换成的背景颜色 为null时背景为透明
* @param tolerance 容差值[根据图片的主题色,加入容差值,值的取值范围在0~255之间]
* @return 返回处理结果 true:图片处理完成 false:图片处理失败
*/
public static boolean backgroundRemoval(final File input, final File output, final Color override, final int tolerance) {
if (fileTypeValidation(input, IMAGES_TYPE)) {
return false;
}
public static void backgroundRemoval(final File input, final File output, final Color override, final int tolerance) {
fileTypeValidation(input, IMAGES_TYPE);
BufferedImage bufferedImage = null;
try {
// 获取图片左上中上右上右中右下下中左下左中8个像素点rgb的16进制值
final BufferedImage bufferedImage = ImageIO.read(input);
bufferedImage = ImgUtil.read(input);
// 图片输出的格式为 png
return ImageIO.write(backgroundRemoval(bufferedImage, override, tolerance), "png", output);
} catch (final IOException e) {
throw new IORuntimeException(e);
ImgUtil.write(backgroundRemoval(bufferedImage, override, tolerance), output);
} finally {
ImgUtil.flush(bufferedImage);
}
}
@ -348,18 +343,14 @@ public class BackgroundRemoval {
*
* @param input 需要进行验证的文件
* @param imagesType 文件包含的类型数组
* @return 返回布尔值 false:给定文件的文件类型在文件数组中 true:给定文件的文件类型 不在给定数组中
*/
private static boolean fileTypeValidation(final File input, final String[] imagesType) {
if (!input.exists()) {
throw new IllegalArgumentException("给定文件为空");
}
private static void fileTypeValidation(final File input, final String[] imagesType) {
Assert.isTrue(input.exists(), "File {} not exist!", input);
// 获取图片类型
final String type = FileTypeUtil.getType(input);
// 类型对比
if (!ArrayUtil.contains(imagesType, type)) {
throw new IllegalArgumentException(StrUtil.format("文件类型{}不支持", type));
}
return false;
throw new IllegalArgumentException(StrUtil.format("Format {} of File not supported!", type));
}
}
}

View File

@ -19,6 +19,9 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.FontMetrics;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@ -119,4 +122,19 @@ public class FontUtil {
return new Dimension(width, height);
}
/**
* 获取font的样式应用在str上的整个矩形
*
* @param str 字符串必须非空
* @param font 字体必须非空
* @return {@link Rectangle2D}
* @since 5.3.3
*/
public static Rectangle2D getRectangle(final String str, final Font font) {
return font.getStringBounds(str,
new FontRenderContext(AffineTransform.getScaleInstance(1, 1),
false,
false));
}
}

View File

@ -185,8 +185,8 @@ public class GraphicsUtil {
* @return 画笔对象
*/
public static Graphics drawImg(final Graphics g, final Image img, final Point point) {
return drawImg(g, img,
new Rectangle(point.x, point.y, img.getWidth(null), img.getHeight(null)));
g.drawImage(img, point.x, point.y, null);
return g;
}
/**

View File

@ -758,10 +758,13 @@ public class Img implements Flushable, Serializable {
* 结果类型设定见{@link #setTargetImageType(String)}
*
* @param out 写出到的目标流
* @return this
* @throws IORuntimeException IO异常
*/
public void write(final OutputStream out) throws IORuntimeException {
public Img write(final OutputStream out) throws IORuntimeException {
write(ImgUtil.getImageOutputStream(out));
return this;
}
/**
@ -769,9 +772,10 @@ public class Img implements Flushable, Serializable {
* 结果类型设定见{@link #setTargetImageType(String)}
*
* @param targetImageStream 写出到的目标流
* @return this
* @throws IORuntimeException IO异常
*/
public void write(final ImageOutputStream targetImageStream) throws IORuntimeException {
public Img write(final ImageOutputStream targetImageStream) throws IORuntimeException {
Assert.notBlank(this.targetImageType, "Target image type is blank !");
Assert.notNull(targetImageStream, "Target output stream is null !");
@ -779,6 +783,8 @@ public class Img implements Flushable, Serializable {
Assert.notNull(targetImage, "Target image is null !");
ImgUtil.write(targetImage, this.targetImageType, targetImageStream, this.quality, this.backgroundColor);
return this;
}
/**
@ -786,8 +792,9 @@ public class Img implements Flushable, Serializable {
*
* @param targetFile 目标文件
* @throws IORuntimeException IO异常
* @return this
*/
public void write(final File targetFile) throws IORuntimeException {
public Img write(final File targetFile) throws IORuntimeException {
final String formatName = FileNameUtil.extName(targetFile);
if (StrUtil.isNotBlank(formatName)) {
this.targetImageType = formatName;
@ -805,6 +812,7 @@ public class Img implements Flushable, Serializable {
} finally {
IoUtil.closeQuietly(out);
}
return this;
}
@Override

View File

@ -24,16 +24,18 @@ import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.Color;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.Flushable;
import java.io.IOException;
import java.io.OutputStream;
/**
* 图片写出封装
*/
public class ImgWriter {
public class ImgWriter implements Flushable {
/**
* 创建图片写出器
@ -138,6 +140,16 @@ public class ImgWriter {
}
}
@Override
public void flush() {
final RenderedImage renderedImage = this.image;
if(renderedImage instanceof BufferedImage){
ImgUtil.flush((BufferedImage) renderedImage);
} else if(renderedImage instanceof Image){
ImgUtil.flush((Image) renderedImage);
}
}
/**
* 构建图片写出参数
*

View File

@ -107,6 +107,7 @@ public class ImgTest {
final Image img = ImgUtil.getImage(UrlUtil.getURL(file));
ImgUtil.scale(img, fileScale, 0.8f);
ImgUtil.flush(img);
}
@Test