ImgUtil的sliceByRowsAndCols背景无法透明问题

This commit is contained in:
Looly 2023-10-27 21:47:56 +08:00
parent b7746fb230
commit eeed094f92
5 changed files with 50 additions and 43 deletions

View File

@ -26,6 +26,7 @@ import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.HybridBinarizer; import com.google.zxing.common.HybridBinarizer;
import java.awt.Image; import java.awt.Image;
import java.awt.image.BufferedImage;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -74,7 +75,8 @@ public class QrDecoder implements Decoder<Image, String> {
final MultiFormatReader formatReader = new MultiFormatReader(); final MultiFormatReader formatReader = new MultiFormatReader();
formatReader.setHints(hints); formatReader.setHints(hints);
final LuminanceSource source = new BufferedImageLuminanceSource(ImgUtil.toBufferedImage(image)); final LuminanceSource source = new BufferedImageLuminanceSource(
ImgUtil.castToBufferedImage(image, ImgUtil.IMAGE_TYPE_JPG));
Result result = _decode(formatReader, new HybridBinarizer(source)); Result result = _decode(formatReader, new HybridBinarizer(source));
if (null == result) { if (null == result) {

View File

@ -135,7 +135,7 @@ public class Img implements Serializable {
* @return Img * @return Img
*/ */
public static Img from(final Image image) { public static Img from(final Image image) {
return new Img(ImgUtil.toBufferedImage(image)); return new Img(ImgUtil.castToBufferedImage(image, ImgUtil.IMAGE_TYPE_JPG));
} }
/** /**
@ -368,7 +368,8 @@ public class Img implements Serializable {
final Image srcImage = getValidSrcImg(); final Image srcImage = getValidSrcImg();
fixRectangle(rectangle, srcImage.getWidth(null), srcImage.getHeight(null)); fixRectangle(rectangle, srcImage.getWidth(null), srcImage.getHeight(null));
final ImageFilter cropFilter = new CropImageFilter(rectangle.x, rectangle.y, rectangle.width, rectangle.height); final ImageFilter cropFilter = new CropImageFilter(
rectangle.x, rectangle.y, rectangle.width, rectangle.height);
this.targetImage = ImgUtil.filter(cropFilter, srcImage); this.targetImage = ImgUtil.filter(cropFilter, srcImage);
return this; return this;
} }
@ -685,8 +686,8 @@ public class Img implements Serializable {
*/ */
public Img stroke(final Color color, final Stroke stroke) { public Img stroke(final Color color, final Stroke stroke) {
final BufferedImage image = ImgUtil.toBufferedImage(getValidSrcImg(), this.targetImageType); final BufferedImage image = ImgUtil.toBufferedImage(getValidSrcImg(), this.targetImageType);
final int width = image.getWidth(null); final int width = image.getWidth();
final int height = image.getHeight(null); final int height = image.getHeight();
final Graphics2D g = image.createGraphics(); final Graphics2D g = image.createGraphics();
g.setColor(ObjUtil.defaultIfNull(color, Color.BLACK)); g.setColor(ObjUtil.defaultIfNull(color, Color.BLACK));

View File

@ -445,17 +445,13 @@ public class ImgUtil {
* 图像切割指定切片的行数和列数 * 图像切割指定切片的行数和列数
* *
* @param srcImageFile 源图像文件 * @param srcImageFile 源图像文件
* @param destDir 切片目标文件夹 * @param targetDir 切片目标文件夹
* @param formatName 格式名称即图片格式后缀 * @param formatName 格式名称即图片格式后缀
* @param rows 目标切片行数默认2必须是范围 [1, 20] 之内 * @param rows 目标切片行数默认2必须是范围 [1, 20] 之内
* @param cols 目标切片列数默认2必须是范围 [1, 20] 之内 * @param cols 目标切片列数默认2必须是范围 [1, 20] 之内
*/ */
public static void sliceByRowsAndCols(final File srcImageFile, final File destDir, final String formatName, final int rows, final int cols) { public static void sliceByRowsAndCols(final File srcImageFile, final File targetDir, final String formatName, final int rows, final int cols) {
try { sliceByRowsAndCols(read(srcImageFile), targetDir, formatName, rows, cols);
sliceByRowsAndCols(ImageIO.read(srcImageFile), destDir, formatName, rows, cols);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
} }
/** /**
@ -474,7 +470,6 @@ public class ImgUtil {
throw new IllegalArgumentException("Destination must be a Directory !"); throw new IllegalArgumentException("Destination must be a Directory !");
} }
try {
if (rows <= 0 || rows > 20) { if (rows <= 0 || rows > 20) {
rows = 2; // 切片行数 rows = 2; // 切片行数
} }
@ -482,25 +477,21 @@ public class ImgUtil {
cols = 2; // 切片列数 cols = 2; // 切片列数
} }
// 读取源图像 // 读取源图像
final BufferedImage bi = toBufferedImage(srcImage); final int srcWidth = srcImage.getWidth(null); // 源图宽度
final int srcWidth = bi.getWidth(); // 源图宽度 final int srcHeight = srcImage.getHeight(null); // 源图高度
final int srcHeight = bi.getHeight(); // 源图高度
final int destWidth = NumberUtil.partValue(srcWidth, cols); // 每张切片的宽度 final int targetWidth = NumberUtil.partValue(srcWidth, cols); // 每张切片的宽度
final int destHeight = NumberUtil.partValue(srcHeight, rows); // 每张切片的高度 final int targetHeight = NumberUtil.partValue(srcHeight, rows); // 每张切片的高度
// 循环建立切片 // 循环建立切片
Image tag; Image tag;
for (int i = 0; i < rows; i++) { for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) { for (int j = 0; j < cols; j++) {
tag = cut(bi, new Rectangle(j * destWidth, i * destHeight, destWidth, destHeight)); tag = cut(srcImage, new Rectangle(j * targetWidth, i * targetHeight, targetWidth, targetHeight));
// 输出为文件 // 输出为文件
ImageIO.write(toRenderedImage(tag), formatName, new File(destDir, "_r" + i + "_c" + j + ".jpg")); write(tag, new File(destDir, "_r" + i + "_c" + j + "." + formatName));
} }
} }
} catch (final IOException e) {
throw new IORuntimeException(e);
}
} }
// endregion // endregion
@ -558,8 +549,9 @@ public class ImgUtil {
* @since 4.1.14 * @since 4.1.14
*/ */
public static void convert(final Image srcImage, final String formatName, final ImageOutputStream destImageStream, final boolean isSrcPng) { public static void convert(final Image srcImage, final String formatName, final ImageOutputStream destImageStream, final boolean isSrcPng) {
final BufferedImage src = toBufferedImage(srcImage, isSrcPng ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
try { try {
ImageIO.write(isSrcPng ? copyImage(srcImage, BufferedImage.TYPE_INT_RGB) : toBufferedImage(srcImage), formatName, destImageStream); ImageIO.write(src, formatName, destImageStream);
} catch (final IOException e) { } catch (final IOException e) {
throw new IORuntimeException(e); throw new IORuntimeException(e);
} }
@ -1148,30 +1140,32 @@ public class ImgUtil {
* 首先尝试强转否则新建一个{@link BufferedImage}后重新绘制使用 {@link BufferedImage#TYPE_INT_RGB} 模式 * 首先尝试强转否则新建一个{@link BufferedImage}后重新绘制使用 {@link BufferedImage#TYPE_INT_RGB} 模式
* *
* @param img {@link Image} * @param img {@link Image}
* @param imageType 目标图片类型例如jpg或png等
* @return {@link BufferedImage} * @return {@link BufferedImage}
* @since 4.3.2 * @since 4.3.2
*/ */
public static RenderedImage toRenderedImage(final Image img) { public static RenderedImage castToRenderedImage(final Image img, final String imageType) {
if (img instanceof RenderedImage) { if (img instanceof RenderedImage) {
return (RenderedImage) img; return (RenderedImage) img;
} }
return copyImage(img, BufferedImage.TYPE_INT_RGB); return toBufferedImage(img, imageType);
} }
/** /**
* {@link Image} {@link BufferedImage}<br> * {@link Image} {@link BufferedImage}<br>
* 首先尝试强转否则新建一个{@link BufferedImage}后重新绘制使用 {@link BufferedImage#TYPE_INT_RGB} 模式 * 首先尝试强转否则新建一个{@link BufferedImage}后重新绘制使用 imageType 模式
* *
* @param img {@link Image} * @param img {@link Image}
* @param imageType 目标图片类型例如jpg或png等
* @return {@link BufferedImage} * @return {@link BufferedImage}
*/ */
public static BufferedImage toBufferedImage(final Image img) { public static BufferedImage castToBufferedImage(final Image img, final String imageType) {
if (img instanceof BufferedImage) { if (img instanceof BufferedImage) {
return (BufferedImage) img; return (BufferedImage) img;
} }
return copyImage(img, BufferedImage.TYPE_INT_RGB); return toBufferedImage(img, imageType);
} }
/** /**

View File

@ -69,7 +69,7 @@ public class ImgWriter {
* @param imageType 图片类型图片扩展名{@code null}表示使用RGB模式JPG * @param imageType 图片类型图片扩展名{@code null}表示使用RGB模式JPG
*/ */
public ImgWriter(final Image image, final String imageType) { public ImgWriter(final Image image, final String imageType) {
this.image = ImgUtil.toRenderedImage(image); this.image = ImgUtil.castToRenderedImage(image, imageType);
this.writer = ImgUtil.getWriter(image, imageType); this.writer = ImgUtil.getWriter(image, imageType);
} }

View File

@ -62,7 +62,9 @@ public class ImgUtilTest {
@Test @Test
@Disabled @Disabled
public void cutTest() { public void cutTest() {
ImgUtil.cut(FileUtil.file("d:/face.jpg"), FileUtil.file("d:/face_result.jpg"), new Rectangle(200, 200, 100, 100)); ImgUtil.cut(FileUtil.file("d:/test/hutool.png"),
FileUtil.file("d:/test/result.png"),
new Rectangle(0, 0, 400, 240));
} }
@Test @Test
@ -106,6 +108,14 @@ public class ImgUtilTest {
ImgUtil.sliceByRowsAndCols(FileUtil.file("d:/test/logo.jpg"), FileUtil.file("d:/test/dest"), ImgUtil.IMAGE_TYPE_JPEG, 1, 5); ImgUtil.sliceByRowsAndCols(FileUtil.file("d:/test/logo.jpg"), FileUtil.file("d:/test/dest"), ImgUtil.IMAGE_TYPE_JPEG, 1, 5);
} }
@Test
@Disabled
public void sliceByRowsAndColsTest2() {
ImgUtil.sliceByRowsAndCols(
FileUtil.file("d:/test/hutool.png"),
FileUtil.file("d:/test/dest"), ImgUtil.IMAGE_TYPE_PNG, 1, 5);
}
@Test @Test
@Disabled @Disabled
public void convertTest() { public void convertTest() {