From acb0ddfd23901382fa23b508905a383a9af9f1e9 Mon Sep 17 00:00:00 2001 From: obo Date: Tue, 5 Sep 2023 10:13:41 +0800 Subject: [PATCH 1/5] =?UTF-8?q?REPORT-103847=20=E5=AF=BC=E5=87=BA=E5=90=8E?= =?UTF-8?q?=E8=93=9D=E8=89=B2=E5=9B=BE=E7=89=87=E4=B8=8D=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/third/com/lowagie/text/Image.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/Image.java b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/Image.java index b583af20a..515160b54 100644 --- a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/Image.java +++ b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/Image.java @@ -757,8 +757,25 @@ public abstract class Image extends Rectangle { transparency[0] = transparency[1] = (transparentPixel >> 16) & 0xff; transparency[2] = transparency[3] = (transparentPixel >> 8) & 0xff; transparency[4] = transparency[5] = transparentPixel & 0xff; + // Added by Michael Klink + // Check whether this value for transparent pixels + // has already been used for a non-transparent one + // before this position + for (int prevPixel = 0; prevPixel < j; prevPixel++) { + if ((pixels[prevPixel] & 0xffffff) == transparentPixel) { + // found a prior use of the transparentPixel color + // and, therefore, cannot make use of this color + // for transparency; we could still use an image + // mask but for simplicity let's use a soft mask + // which already is implemented here + shades = true; + break; + } + } } - } else if ((pixels[j] & 0xffffff) != transparentPixel) { + } else if (((pixels[j] & 0xffffff) != transparentPixel) && (alpha == 0)) { + shades = true; + } else if (((pixels[j] & 0xffffff) == transparentPixel) && (alpha != 0)) { shades = true; } } From 2d7f260d19b399c57e6610dfb97deac62954f8aa Mon Sep 17 00:00:00 2001 From: obo Date: Wed, 6 Sep 2023 14:33:00 +0800 Subject: [PATCH 2/5] =?UTF-8?q?REPORT-103847=20=E4=BC=98=E5=8C=96=E8=A1=A5?= =?UTF-8?q?=E5=85=85=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/fr/third/com/lowagie/text/Image.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/Image.java b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/Image.java index 515160b54..4e534db31 100644 --- a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/Image.java +++ b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/Image.java @@ -753,10 +753,6 @@ public abstract class Image extends Rectangle { } else if (transparency == null) { if (alpha == 0) { transparentPixel = pixels[j] & 0xffffff; - transparency = new int[6]; - transparency[0] = transparency[1] = (transparentPixel >> 16) & 0xff; - transparency[2] = transparency[3] = (transparentPixel >> 8) & 0xff; - transparency[4] = transparency[5] = transparentPixel & 0xff; // Added by Michael Klink // Check whether this value for transparent pixels // has already been used for a non-transparent one @@ -768,10 +764,15 @@ public abstract class Image extends Rectangle { // for transparency; we could still use an image // mask but for simplicity let's use a soft mask // which already is implemented here + // stackOverFlow:https://stackoverflow.com/questions/39119776/itext-binary-transparency-bug shades = true; break; } } + transparency = new int[6]; + transparency[0] = transparency[1] = (transparentPixel >> 16) & 0xff; + transparency[2] = transparency[3] = (transparentPixel >> 8) & 0xff; + transparency[4] = transparency[5] = transparentPixel & 0xff; } } else if (((pixels[j] & 0xffffff) != transparentPixel) && (alpha == 0)) { shades = true; From f07bced888f5b8ade34265b15a6338c0e0208366 Mon Sep 17 00:00:00 2001 From: obo Date: Wed, 6 Sep 2023 15:50:16 +0800 Subject: [PATCH 3/5] =?UTF-8?q?REPORT-103847=20=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/third/com/lowagie/text/ImageTest.java | 108 ++++++++++++++++++ .../com/fr/third/com/lowagie/text/actual.pdf | Bin 0 -> 1601 bytes .../com/fr/third/com/lowagie/text/expect.pdf | Bin 0 -> 1601 bytes .../com/lowagie/text/transparent_image.png | Bin 0 -> 247 bytes 4 files changed, 108 insertions(+) create mode 100644 fine-itext-old/test/com/fr/third/com/lowagie/text/ImageTest.java create mode 100644 fine-itext-old/test/com/fr/third/com/lowagie/text/actual.pdf create mode 100644 fine-itext-old/test/com/fr/third/com/lowagie/text/expect.pdf create mode 100644 fine-itext-old/test/com/fr/third/com/lowagie/text/transparent_image.png diff --git a/fine-itext-old/test/com/fr/third/com/lowagie/text/ImageTest.java b/fine-itext-old/test/com/fr/third/com/lowagie/text/ImageTest.java new file mode 100644 index 000000000..699d98d92 --- /dev/null +++ b/fine-itext-old/test/com/fr/third/com/lowagie/text/ImageTest.java @@ -0,0 +1,108 @@ +import com.fr.third.com.lowagie.text.Document; +import com.fr.third.com.lowagie.text.RectangleReadOnly; +import com.fr.third.com.lowagie.text.pdf.PdfContentByte; +import com.fr.third.com.lowagie.text.pdf.PdfGraphics2D; +import com.fr.third.com.lowagie.text.pdf.PdfTemplate; +import com.fr.third.com.lowagie.text.pdf.PdfWriter; +import org.junit.Test; +import org.junit.Assert; + +import javax.imageio.ImageIO; +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Arrays; + + + +/** + * Image单元测试类 + * 不在打包范围内,只是留个凭证,需要自己添加junit 依赖才能跑 + * + * @author obo + * @since 11.0 + * Created on 2023/9/6 + */ +public class ITextDrawPdfImageTest { + + @Test + public void testDrawOpaqueAndTransparentImage() throws Exception { + // 创建文档对象 + Document document = new Document(new RectangleReadOnly(90,90)); + // 创建PdfWriter以将文档写入文件 + PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("actual.pdf")); + BufferedImage image = ImageIO.read(new File("transparent_image.png")); + + Assert.assertTrue(checkImageValid(image)); + + // 打开文档 + document.open(); + + // 获取PdfContentByte用于在PDF页面上绘制内容 + PdfContentByte contentByte = writer.getDirectContent(); + + // 创建PdfTemplate,作为图形容器 + PdfTemplate template = contentByte.createTemplate(90, 90); + PdfGraphics2D graphics2D = (PdfGraphics2D) template.createGraphics(90, 90); + + // 在Graphics2D上绘制图像或其他内容 + graphics2D.drawImage(image, 0, 0, null); + + // 释放Graphics2D资源 + graphics2D.dispose(); + + // 将PdfTemplate添加到PDF页面 + contentByte.addTemplate(template, 0, 0); // X, Y 坐标 + // 关闭文档 + document.close(); + + File actual = new File("actual.pdf"); + File expect = new File("expect.pdf"); + + Assert.assertTrue(checkFilesEqual(actual, expect)); + } + + + private boolean checkFilesEqual(File actual, File expect) throws IOException { + byte[] actualBytes = Arrays.copyOfRange(Files.readAllBytes(actual.toPath()), 0, 1024); + byte[] expectBytes = Arrays.copyOfRange(Files.readAllBytes(expect.toPath()), 0, 1024); + + return java.util.Arrays.equals(actualBytes, expectBytes); + } + + /** + * 检查Image是否是一种完全透明颜色+一种完全不透明颜色构成的 + */ + private boolean checkImageValid(BufferedImage image) { + int transparentColor = -1, unTransparentColor = -1; + + int width = image.getWidth(); + int height = image.getHeight(); + + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + int rgb = image.getRGB(x, y); + int alpha = (rgb >> 24) & 0xFF; + int color = rgb & 0xFFFFFF; + if(alpha == 0) { + if (transparentColor == -1) { + transparentColor = color; + } else if (transparentColor != color) { + return false; + } + } + if(alpha == 255) { + if (unTransparentColor == -1) { + unTransparentColor = color; + } else if (unTransparentColor != color) { + return false; + } + } + } + } + return true; + } +} \ No newline at end of file diff --git a/fine-itext-old/test/com/fr/third/com/lowagie/text/actual.pdf b/fine-itext-old/test/com/fr/third/com/lowagie/text/actual.pdf new file mode 100644 index 0000000000000000000000000000000000000000..dbc229d9f4385ed935a9f5e4a3a7eb3d30924bf1 GIT binary patch literal 1601 zcmds1&1(}u6tALE7X=YT+k?&}n6}uN+3apMQi3Ki8Z{V`fQ6XD?CvD4COdI9t`y9Z@F=M0rU`!cR$*zv5hq#{ z=9;8V;cn{J4-0@1f?2;ID2Lew5i~-o9<9G2qKmjOAKj4|u1)J!37H4_bJKkF zv^FzbMrG8O>c4*T?yb!iYj>tD-Cy%;dEeB>m5&$iX!dqYvp`7lLZD7joTa^>Odxg{z<1xi5zSf*_OW>u8xj_K~0tIml=rj6Gyz-rl~G*}>9sl@2)lc%0f zQmkD;@-v~HYBH$~ssK?rU7gQKHp_VPuQJUO!TmOzB!ULo5YjFS+6!8yJj! z>(!R+}>xLH-szB``w%7N< ziXymJ?XelkhA|<*$1qnOFGuxJJQ^SB0dDouJ9VEXf;3oNQdXzoEMvXkcrQ55yo_ua z(abg-=`oZ*7B-EzX^kLz3qo6lU|O~V;j`e+QBq#sgiCqU?vHD5Y`i>7K!ZKpVfW)+x zs-wCRd;9Lyq@n=?XzhqHHU`tQL0PHgxCCa%@xUd;T`8D%qNAXqVGMrvR$*zP#!s{e z%r%`lfxAgiKg@xO5X=S*P8iHK98NOCr5=H0892Vbc7(Vb9t=EwxD&aLgmp31EFGo- z9u){n(`Ji?B;>$KCL_*>(^T3wKfm6w`t0_;W$O1E$yG0|T|V@1?a7xf7TDDN+Iqe=Q*T{}-X9wnz8nn)HC@je}?PjoX9jtp>Yy{)`_!I(L5WlN8v{zqD_1)4Jisgi27mi0uu$ zs3Hk2R(otlqG3!3@Ku;AkC)@xs5)v6^#C_|>7BYyJKSl|x}dC1qFKgz!DcTwPrZz2 z8S%_E4QUBvBSXarO|?gmwFRLqLohAc0S{>S=O`gBZ^9)k9(0t|IUT5-0BSigUY>W% zHY2`*fTf_H1`Lc782Dh$XJQ+4{(|tQ52*qVY4d!#B`&?try^rV!Z literal 0 HcmV?d00001 diff --git a/fine-itext-old/test/com/fr/third/com/lowagie/text/transparent_image.png b/fine-itext-old/test/com/fr/third/com/lowagie/text/transparent_image.png new file mode 100644 index 0000000000000000000000000000000000000000..820cc05ca814d2542d6584aed420b8450753633b GIT binary patch literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^DIm~)z1S$opuoXw_$_|d zu2znhcl9rXObVJmhrz|6frCSUkx@y(0foZ?k*MV;n$F3{$i%`Spy1HJKt;w0JBY0; hEFEwcpt0jh8J4;FaD=%vngV^o;OXk;vd$@?2>>_tFYN#T literal 0 HcmV?d00001 From 65e754ca3cdf1e6f2f6d9a84713f720c726d62a4 Mon Sep 17 00:00:00 2001 From: "Bruce.Deng" Date: Tue, 19 Sep 2023 11:53:50 +0800 Subject: [PATCH 4/5] =?UTF-8?q?REPORT-103466=20=E5=AF=BC=E5=87=BA=E8=B4=9F?= =?UTF-8?q?=E8=BD=BD=E9=AB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/third/com/lowagie/text/pdf/ByteBuffer.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/ByteBuffer.java b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/ByteBuffer.java index e48934ef0..854ae0133 100644 --- a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/ByteBuffer.java +++ b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/ByteBuffer.java @@ -82,6 +82,7 @@ public class ByteBuffer extends OutputStream { */ public static boolean HIGH_PRECISION = false; private static final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US); + private static final int HALF_INTEGER = Integer.MAX_VALUE >> 1; /** Creates new ByteBuffer with capacity 128 */ public ByteBuffer() { @@ -189,7 +190,7 @@ public class ByteBuffer extends OutputStream { public ByteBuffer append_i(int b) { int newcount = count + 1; if (newcount > buf.length) { - byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)]; + byte newbuf[] = new byte[Math.max(Math.min(buf.length, HALF_INTEGER) << 1, newcount)]; System.arraycopy(buf, 0, newbuf, 0, count); buf = newbuf; } @@ -212,7 +213,7 @@ public class ByteBuffer extends OutputStream { return this; int newcount = count + len; if (newcount > buf.length) { - byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)]; + byte newbuf[] = new byte[Math.max(Math.min(buf.length, HALF_INTEGER) << 1, newcount)]; System.arraycopy(buf, 0, newbuf, 0, count); buf = newbuf; } From 75a5739ee5422d77ababa42b8df32966340f1117 Mon Sep 17 00:00:00 2001 From: "Bruce.Deng" Date: Tue, 19 Sep 2023 15:14:47 +0800 Subject: [PATCH 5/5] =?UTF-8?q?REPORT-103466=20=E5=AF=BC=E5=87=BA=E8=B4=9F?= =?UTF-8?q?=E8=BD=BD=E9=AB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/third/com/lowagie/text/pdf/ByteBuffer.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/ByteBuffer.java b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/ByteBuffer.java index 854ae0133..e71127490 100644 --- a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/ByteBuffer.java +++ b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/ByteBuffer.java @@ -189,6 +189,9 @@ public class ByteBuffer extends OutputStream { */ public ByteBuffer append_i(int b) { int newcount = count + 1; + if (newcount < 0) { + throw new OutOfMemoryError(); + } if (newcount > buf.length) { byte newbuf[] = new byte[Math.max(Math.min(buf.length, HALF_INTEGER) << 1, newcount)]; System.arraycopy(buf, 0, newbuf, 0, count); @@ -212,6 +215,9 @@ public class ByteBuffer extends OutputStream { ((off + len) > b.length) || ((off + len) < 0) || len == 0) return this; int newcount = count + len; + if (newcount < 0) { + throw new OutOfMemoryError(); + } if (newcount > buf.length) { byte newbuf[] = new byte[Math.max(Math.min(buf.length, HALF_INTEGER) << 1, newcount)]; System.arraycopy(buf, 0, newbuf, 0, count);