当前位置: 首页 > 知识库问答 >
问题:

PNG在spring mapping中生成的图像不适用于apache FOP生成的PDF

冀越
2023-03-14

首先,这不是像这个链接中的情况

Java Applet中的Apache FOP-未找到数据的ImagePreloader

由于所有图像(包括PNG)都正常显示,除了由Spring映射动态生成的图像。

所以,也就是说,我有以下情况。我有一个带有这个映射的控制器:

    @GetMapping(value = {
        "/static/test/qr.png"
    }, produces = MediaType.IMAGE_PNG_VALUE)
    public void genericQR(HttpServletRequest request, HttpServletResponse response) throws WriterException, IOException {
        response.setContentType("image/png");
        final byte[] bytes = new QrCodeGenerator().generate("HELLO", null);
        response.setContentLength(bytes.length);
        response.getOutputStream().write(bytes);
    }

QrCodeGenerator类如下:

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author jpaoletti
 */
public class QrCodeGenerator {

    private final int width;
    private final int height;

    public QrCodeGenerator() {
        width = 400;
        height = 400;
    }

    public QrCodeGenerator(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public byte[] generate(String content, String logo) throws WriterException, IOException {
        // Create new configuration that specifies the error correction
        Map<EncodeHintType, ErrorCorrectionLevel> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

        QRCodeWriter writer = new QRCodeWriter();
        BitMatrix bitMatrix = null;
        ByteArrayOutputStream os = new ByteArrayOutputStream();

        // Create a qr code with the url as content and a size of WxH px
        bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

        // Load QR image
        BufferedImage qrImage = MatrixToImageWriter.toBufferedImage(bitMatrix, getMatrixConfig());

        // Load logo image
        BufferedImage overly = logo == null ? null : getOverly(logo);

        // Calculate the delta height and width between QR code and logo
        int deltaHeight = overly == null ? null : (qrImage.getHeight() - overly.getHeight());
        int deltaWidth = overly == null ? null : (qrImage.getWidth() - overly.getWidth());

        // Initialize combined image
        BufferedImage combined = new BufferedImage(qrImage.getHeight(), qrImage.getWidth(), BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = (Graphics2D) combined.getGraphics();

        // Write QR code to new image at position 0/0
        g.drawImage(qrImage, 0, 0, null);
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
        if (overly != null) {
            g.drawImage(overly, (int) Math.round(deltaWidth / 2), (int) Math.round(deltaHeight / 2), null);
        }
        ImageIO.write(combined, "png", os);
        return os.toByteArray();
    }

    private BufferedImage getOverly(String LOGO) throws IOException {
        URL url = new URL(LOGO);
        return ImageIO.read(url);
    }

    private MatrixToImageConfig getMatrixConfig() {
        // ARGB Colors
        // Check Colors ENUM
        return new MatrixToImageConfig(QrCodeGenerator.Colors.BLACK.getArgb(), QrCodeGenerator.Colors.WHITE.getArgb());
    }

    public enum Colors {

        BLUE(0xFF40BAD0),
        RED(0xFFE91C43),
        PURPLE(0xFF8A4F9E),
        ORANGE(0xFFF4B13D),
        WHITE(0xFFFFFFFF),
        BLACK(0xFF000000);

        private final int argb;

        Colors(final int argb) {
            this.argb = argb;
        }

        public int getArgb() {
            return argb;
        }
    }
}

从网站或浏览器直接访问图像很好,但尝试将其包含在apache fop生成的pdf中会引发以下错误:

2021/09/29 09:08:47 [http-nio-8084-exec-73] ERROR org.apache.fop.apps.FOUserAgent  - Image not available. URI: http://localhost:8084/static/test/qr.png. Reason: org.apache.xmlgraphics.image.loader.ImageException: The file format is not supported. No ImagePreloader found for http://localhost:8084/static/test/qr.png (No context info available)
org.apache.xmlgraphics.image.loader.ImageException: The file format is not supported. No ImagePreloader found for http://localhost:8084/static/test/qr.png
    at org.apache.xmlgraphics.image.loader.ImageManager.preloadImage(ImageManager.java:181)
    at org.apache.xmlgraphics.image.loader.cache.ImageCache.needImageInfo(ImageCache.java:127)
    at org.apache.xmlgraphics.image.loader.ImageManager.getImageInfo(ImageManager.java:123)

我试过很多选项,甚至换成JPG也有同样的结果。有什么想法吗?

本工程

  <fo:block>
   <fo:external-graphic src="url('{$url-base}/static/img/logosite.png')" content-height="scale-to-fit" height="1cm" />
  </fo:block>

这行不通

  <fo:block font-size="10pt" margin-top="0cm">
    <fo:external-graphic src="url('{$url-base}/static/test/qr.png')" content-height="scale-to-fit" height="3cm" content-width="3cm" scaling="non-uniform" />
  </fo:block>

预先感谢

共有1个答案

何长恨
2023-03-14

原来是一个安全问题。从浏览器我可以访问,但只是因为我已登录。如果我尝试在不登录的情况下获取图像,则会弹出安全错误。

所以,解决方案是利用控制器模式和安全性:http拦截url

 类似资料:
  • 我试图使用Apache Fop和Java生成PDF,但生成的Pdf总是一个空白页。它都嵌套在一个网络应用程序中,割断器是玻璃鱼。 有人有什么建议吗? 以下是我的xsl: 示例XML文件如下所示: 编辑:应该生成pdf的Java代码。。。 第二次编辑: 我发现我的outputStream有问题。我想显示另存为对话框,以便从web应用程序下载生成的文件。我不明白,我的输出有什么问题。。。

  • 我正试图用我的MERN stack web应用程序自动化构建过程。 目前,我使用CodePipeline,它: 从GitHub获取我的代码作为源代码 使用CodeBuild(Ubuntu 2.0)运行构建 并将其部署到我的Elastic BeanStalk环境中 步骤1 在尝试使用CodeBuild之后,即使客户端似乎完全按照日志进行构建,前端似乎也不会更新。 以下是我CodeBuild项目的一些

  • API 2:GET:/school/student/all

  • 我正在使用assets文件夹中的hdpi、mdpi、xhdpi,xxhdpi和xxxhdpi来响应本地android。 但是有些图像工作正常,有时即使在提供固定的高度和宽度后,相同的图像也会调整大小(大小增加和减小)。 对于ios来说一切都很好,但是在Android的情况下,图像会失真,有时无法显示。 我已尽一切努力解决此问题,但尚无法解决。

  • 我正在用apache fop库(v2.2)生成PDF文件。如果我从Eclipse IDE运行应用程序,所有运行都没有问题,但是如果我从Eclipse IDE生成JAR,并且库处理设置为将所需的库提取到生成的JAR中,然后我将运行JAR,它将生成没有图像的PDF文件(文本如预期的那样可见)。首先我认为这是由无效的文件路径引起的,但是如果我直接在XSL中使用base64编码的图像,图像仍然不可见。如果

  • 问题内容: 我在用 单击到容器上的按钮,但随后进行了ajax调用,并且内容使用新内容进行了更新,然后当我尝试单击它时将无法工作…单击该按钮时,将不会返回任何内容。 我什至试过 要么 我该如何运作? 编辑: 我的HTML: 问题答案: 应该以这种方式完成。 如果您的容器在ajax请求期间没有更改,则性能更高: 始终将委托事件绑定到将包含动态元素的最接近的静态元素。