gpt4 book ai didi

image - 在 IText XMLWorker 中处理嵌入图像

转载 作者:行者123 更新时间:2023-12-04 02:13:28 25 4
gpt4 key购买 nike

在 IText XMLWorker 中处理嵌入的图像。

有没有办法在 XMLWorker 中处理嵌入式 (Base64) 图像?在版本 5.3.5我使用的 ImageProvider 不再工作(之前引发异常),所以我按如下方式修补了 ImageRetrieve,但显然这将在接下来被打破XMLWorker 更新:

package com.itextpdf.tool.xml.net;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.codec.Base64;
import com.itextpdf.tool.xml.net.exc.NoImageException;
import com.itextpdf.tool.xml.pipeline.html.ImageProvider;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
* @author redlab_b
*
*/
public class ImageRetrieve {
final static Pattern INLINE_PATTERN = Pattern.compile("^/data:image/(png|jpg|gif);base64,(.*)");

private final ImageProvider provider;
/**
* @param imageProvider the provider to use.
*
*/
public ImageRetrieve(final ImageProvider imageProvider) {
this.provider = imageProvider;
}
/**
*
*/
public ImageRetrieve() {
this.provider = null;
}
/**
* @param src an URI that can be used to retrieve an image
* @return an iText Image object
* @throws NoImageException if there is no image
* @throws IOException if an IOException occurred
*/
public com.itextpdf.text.Image retrieveImage(final String src) throws NoImageException, IOException {
com.itextpdf.text.Image img = null;
if (null != provider) {
img = provider.retrieve(src);
}

if (null == img) {
String path = null;
if (src.startsWith("http")) {
// full url available
path = src;
} else if (null != provider){
String root = this.provider.getImageRootPath();
if (null != root) {
if (root.endsWith("/") && src.startsWith("/")) {
root = root.substring(0, root.length() - 1);
}
path = root + src;
}
} else {
path = src;
}
if (null != path) {
try {
Matcher m;
if (path.startsWith("http")) {
img = com.itextpdf.text.Image.getInstance(path);
} else if ((m = INLINE_PATTERN.matcher(path)).matches()) {
// Let's handle the embedded image without saving it
try {
byte[] data = Base64.decode(m.group(2));
return Image.getInstance(data);
} catch (Exception ex) {
throw new NoImageException(src, ex);
}
} else {
img = com.itextpdf.text.Image.getInstance(new File(path).toURI().toURL());
}
if (null != provider && null != img) {
provider.store( src, img);
}
} catch (BadElementException e) {
throw new NoImageException(src, e);
} catch (MalformedURLException e) {
throw new NoImageException(src, e);
}
} else {
throw new NoImageException(src);
}
}
return img;
}



}

最佳答案

你问这个问题已经快一年了,但也许这个答案无论如何都会有所帮助。

最近遇到了类似的问题。我的目标是在生成的 pdf 中包含存储在数据库中的图像。

为此,我扩展了 com.itextpdf.tool.xml.pipeline.html.AbstractImageProvider 类并覆盖了它的 retrieve() 方法,如下所示:

public class MyImageProvider extends AbstractImageProvider {

@Override
public Image retrieve(final String src) {
Image img = super.retrieve(src);
if (img == null) {
try {
byte [] data = getMyImageSomehow(src);
img = Image.getInstance(data);
super.store(src, img);
}
catch (Exception e) {
//handle exceptions
}
}
return img;
}

@Override
public String getImageRootPath() {
return "http://sampleurl/img";
}
}

然后,在为 XMLWorker [1] 构建管道时,我将我的类的一个实例传递给上下文:

htmlPipelineContext.setImageProvider(new MyImageProvider());

现在我们希望这应该有效。但是有一个陷阱!在 xmlworker 库的深处某处,正在克隆此 htmlPipelineContext。在此操作期间,我们的 ImageProvider 实现丢失了。这是在 HtmlPipelineContext 的 clone() 方法中发生的。看一下第274-280行(我指的是5.4.4版本):

final String rootPath =  imageProvider.getImageRootPath();
newCtx.setImageProvider(new AbstractImageProvider() {
public String getImageRootPath() {
return rootPath;
}
});

这甚至在 HtmlPipelineContext.clone() 的 javadoc [2] 中有描述:

Create a clone of this HtmlPipelineContext, the clone only contains the initial values, not the internal values. Beware, the state of the current Context is not copied to the clone. Only the configurational important stuff like the (...) ImageProvider (new AbstractImageProvider with same ImageRootPath) , (...) are copied.

这不是很好笑吗?您通过将其抽象化而获得设计用于扩展的类,但最终证明该类仅用作属性持有者。

我的解决方法:

public class MySpecialImageProviderAwareHtmlPipelineContext extends HtmlPipelineContext {

MySpecialImageProviderAwareHtmlPipelineContext () {
super(null);
}

public HtmlPipelineContext clone () {
HtmlPipelineContext ctx = null;
try {
ctx = super.clone();
ctx.setImageProvider(new MyImageProvider());
} catch (Exception e) {
//handle exception
}
return ctx;
}

}

然后我就用这个代替 HtmlPipelineContext。


[1] http://demo.itextsupport.com/xmlworker/itextdoc/flatsite.html#itextdoc-menu-7

[2] http://api.itextpdf.com/xml/com/itextpdf/tool/xml/pipeline/html/HtmlPipelineContext.html#clone()

关于image - 在 IText XMLWorker 中处理嵌入图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14864369/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com