openhtmltopdf icon indicating copy to clipboard operation
openhtmltopdf copied to clipboard

SVG images not supported as background via CSS

Open nukul4r opened this issue 3 years ago • 10 comments

In our project, we are using PdfRendererBuilder.withW3cDocument to convert a HTML document to PDF. In this input, we use CSS to define a background image:

.logo {
  background-image: url("logo.svg");
}

When the PDF is rendered, we get the following stacktrace:

Can't read image file; unexpected problem for URI '.../logo.svg'

java.io.IOException: Unrecognized Image format
	at com.openhtmltopdf.pdfboxout.PdfBoxImage.<init>(PdfBoxImage.java:44)
	at com.openhtmltopdf.pdfboxout.PdfBoxUserAgent.getImageResource(PdfBoxUserAgent.java:90)
	at com.openhtmltopdf.render.AbstractOutputDevice.getBackgroundImage(AbstractOutputDevice.java:210)
	at com.openhtmltopdf.render.AbstractOutputDevice.paintBackground0(AbstractOutputDevice.java:295)
	at com.openhtmltopdf.render.AbstractOutputDevice.paintBackground(AbstractOutputDevice.java:234)
	at com.openhtmltopdf.pdfboxout.PdfBoxFastOutputDevice.paintBackground(PdfBoxFastOutputDevice.java:283)
	at com.openhtmltopdf.render.Box.paintBackground(Box.java:583)
	at com.openhtmltopdf.render.displaylist.DisplayListPainter.paintBackgroundAndBorders(DisplayListPainter.java:75)
	at com.openhtmltopdf.render.displaylist.DisplayListPainter.paint(DisplayListPainter.java:251)
	at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.paintPageFast(PdfBoxRenderer.java:921)
	at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.writePDFFast(PdfBoxRenderer.java:617)
	at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.createPdfFast(PdfBoxRenderer.java:554)
	at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.createPDF(PdfBoxRenderer.java:480)
	at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.createPDF(PdfBoxRenderer.java:417)
	at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.createPDF(PdfBoxRenderer.java:399)
	at com.openhtmltopdf.pdfboxout.PdfRendererBuilder.run(PdfRendererBuilder.java:46)
[...]

When we add the SVG directly to the HTML (with <img src="classpath:static/public/img/logo.svg"></img>), the image is rendered correctly. To make this work, we add the com.openhtmltopdf.svgsupport.BatikSVGDrawer inPdfRendererBuilder.useSVGDrawer.

The cause seems to be, that the SVG drawer is not used when rendering the background.

Thanks!

nukul4r avatar Aug 24 '21 13:08 nukul4r

Hi, we face to exactly same problem during rendering the SVG file, when we use CSS to define a background image. I have tested it with both relative address and data-URI:

.icon-at {
  background-image: url("images/flag-at.svg");
}

//////// OR ///////

.icon-at {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1000' height='600' viewBox='0 0 5 3'><desc>Flag of Germany</desc><rect id='red_stripe ' width='5' height='3' y='0' x='0' fill='#ed2939'/><rect id='white_stripe' width='5' height='2' y='1' x='0' fill='#FFF'/><rect id='red_stripe2' width='5' height='1' y='2' x='0' fill='#ed2939'/></svg>");
}

omna-manz avatar Sep 20 '21 06:09 omna-manz

Hello again,

By my last check, I have found that might be change code in AbstractOutputDevice.paintBackground0() where is checkd whether backgroundImage is GRADIENT or URI. I think it should be check again if URI contains ".svg", then draws a SVG file instead of Image.

In other words, It should create XMLResource instead of ImageResource.

I hope it was helpful. :)

omna-manz avatar Sep 22 '21 08:09 omna-manz

Thanks @omna-manz,

SVG background images are likely to get in the next release. Stay tuned.

danfickle avatar Sep 26 '21 05:09 danfickle

Thank you @danfickle, It is a great news :)

omna-manz avatar Sep 27 '21 06:09 omna-manz

@danfickle Is there a fix for this issue?

NiroshaDilan avatar Sep 26 '22 10:09 NiroshaDilan

Has anybody found a way to get this to work? Or can we come up with a PR?

jochenberger avatar Nov 16 '22 16:11 jochenberger

See also #583.

jochenberger avatar Nov 18 '22 11:11 jochenberger

I tried to create a PR but I'm not sure where to put the logic. My first attempt was to add the code to the AbstractOutputDevice, but we have no access to the Box there. Then I tried to use the ReplacedElementFactory to turn the SVG into PNG and replace the url, but that didn't seem to have an effect. Can somebody advise? In the meantime, my workaround is to replace the SVG data-urls with PNG data-urls in the HTML as a pre-processing step.

jochenberger avatar Nov 21 '22 11:11 jochenberger

I am also facing the same issue with SVG binary images. They are not getting loaded. I am using docx4j-ImportXHTML (11.4.8) which is calling openhtmltopdf-core(1.0.10). Can someone please help here

Abhinandan578 avatar Dec 06 '23 10:12 Abhinandan578