从数据库显示图像。获取net.sf.jasperreports.engine.JRException:图像读取失败 [英] Show image from database. Getting net.sf.jasperreports.engine.JRException: Image read failed

查看:3284
本文介绍了从数据库显示图像。获取net.sf.jasperreports.engine.JRException:图像读取失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将图像作为二进制数据从我的数据库中拉出并插入到 Jasper Reports 报告中。

I'm trying to pull an image as binary data from my database and insert it into a Jasper Reports report.

使用 Jaspersoft Studio ,我在我的字段中读取并将其类型更改为java.awt.Image。
然后,我将一个图像元素添加到我的报告中并将表达式更改为$ {Attr1_icon}
当我尝试编译时,我得到:

Using Jaspersoft Studio, I read in my field and change it's type to java.awt.Image. Then, I add an image element to my report and change the expression to ${Attr1_icon} When I try to compile, I get:

net.sf.jasperreports.engine.JRException: net.sf.jasperreports.engine.JRException: Unable to get value for field 'Attr1_icon' of class 'java.awt.Image'
at com.jaspersoft.studio.editor.preview.view.control.ReportControler.fillReport(ReportControler.java:482)
at com.jaspersoft.studio.editor.preview.view.control.ReportControler.access$18(ReportControler.java:457)
at com.jaspersoft.studio.editor.preview.view.control.ReportControler$4.run(ReportControler.java:347)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: net.sf.jasperreports.engine.JRException: Unable to get value for field 'Attr1_icon' of class 'java.awt.Image'
at net.sf.jasperreports.engine.JRResultSetDataSource.getFieldValue(JRResultSetDataSource.java:319)
at net.sf.jasperreports.engine.fill.JRFillDataset.setOldValues(JRFillDataset.java:1356)
at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:1257)
at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:1233)
at net.sf.jasperreports.engine.fill.JRBaseFiller.next(JRBaseFiller.java:1577)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:149)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:932)
at net.sf.jasperreports.engine.fill.BaseFillHandle$ReportFiller.run(BaseFillHandle.java:120)
at java.lang.Thread.run(Unknown Source)
Caused by: net.sf.jasperreports.engine.JRException: Image read failed.
at net.sf.jasperreports.engine.util.JRJdk14ImageReader.readImage(JRJdk14ImageReader.java:73)
at net.sf.jasperreports.engine.util.JRImageLoader.loadAwtImageFromBytes(JRImageLoader.java:167)
at net.sf.jasperreports.engine.JRResultSetDataSource.getFieldValue(JRResultSetDataSource.java:309)
Caused by: net.sf.jasperreports.engine.JRException: Image read failed.
at net.sf.jasperreports.engine.util.JRJdk14ImageReader.readImage(JRJdk14ImageReader.java:73)
at net.sf.jasperreports.engine.util.JRImageLoader.loadAwtImageFromBytes(JRImageLoader.java:167)
at net.sf.jasperreports.engine.JRResultSetDataSource.getFieldValue(JRResultSetDataSource.java:309)

导致此异常的源代码来自JRJdk14ImageReader.java:

The source code that caused this exception comes from here in JRJdk14ImageReader.java:

public Image readImage(byte[] bytes) throws JRException {
    InputStream bais = new ByteArrayInputStream(bytes);

    Image image = null;
    try {
        image = ImageIO.read(bais);
    } catch (Exception e) {
        throw new JRException(e);
    } finally {
        try {
            bais.close();
        } catch (IOException e) {
        }
    }

    if (image == null) {
        throw new JRException("Image read failed."); // Line 73
    }

    return image;
}

因此,您可以看到图像为空。但我不明白为什么。我已经确认数据实际存在。如果我将数据类型更改为字符串并将其添加到普通文本字段,则会打印二进制数据。所以,我不认为它是null,因为传入的数据是null。

So, you can see that the image is null. But I don't understand why. I've verified that the data is actually there. If I change the data type to a string and add it to a normal text field, it prints the binary data. So, I don't think it's null because the passed in data is null.

来自 Javadoc

Returns a BufferedImage as the result of decoding a supplied InputStream with an
ImageReader chosen automatically from among those currently registered. The InputStream
is wrapped in an ImageInputStream. If no registered ImageReader claims to be able to
read the resulting stream, null is returned.

所以我猜没有注册的ImageReader?我怎么能通过 Jaspersoft Studio 修复类似的东西?

So I guess there is no registered ImageReader? How could I fix something like that through Jaspersoft Studio?

编辑:我尝试使用java.io.InputStream作为类类型建议此处,但会导致相同的错误。的种类。一个很大的区别是,在 Jaspersoft Studio 中,如果出现错误,您可以将图像设置为显示为空白。如果我使用java.awt.Image,则此设置不执行任何操作。我仍然收到错误,报告没有建立。如果我使用java.io.InputStream,报表会生成,但图像为空。如果我打开错误报告,我会得到类似的堆栈跟踪,但它不完全相同:

I've tried using java.io.InputStream for the class type as suggested here but that results in the same error. Kind of. A big difference is that, in Jaspersoft Studio, you can set the image to show up blank if there is an error. If I use java.awt.Image, then this setting does nothing. I still get an error and the report doesn't build. If I use java.io.InputStream, the report does build, but the image is blank. If I switch on the error reporting, I get a similar stack trace, but it's not quite the same:

net.sf.jasperreports.engine.JRRuntimeException: net.sf.jasperreports.engine.JRException: Image read failed.
at net.sf.jasperreports.engine.export.draw.PrintDrawVisitor.visit(PrintDrawVisitor.java:143)
at net.sf.jasperreports.engine.export.draw.PrintDrawVisitor.visit(PrintDrawVisitor.java:1)
at net.sf.jasperreports.engine.fill.JRTemplatePrintImage.accept(JRTemplatePrintImage.java:451)
at net.sf.jasperreports.engine.export.draw.FrameDrawer.draw(FrameDrawer.java:251)
at net.sf.jasperreports.engine.export.draw.FrameDrawer.draw(FrameDrawer.java:199)
at net.sf.jasperreports.engine.export.JRGraphics2DExporter.exportPage(JRGraphics2DExporter.java:273)
at net.sf.jasperreports.engine.export.JRGraphics2DExporter.exportReportToGraphics2D(JRGraphics2DExporter.java:246)
at net.sf.jasperreports.engine.export.JRGraphics2DExporter.exportReport(JRGraphics2DExporter.java:184)
at net.sf.jasperreports.eclipse.viewer.ViewerCanvas.renderPage(ViewerCanvas.java:369)
at net.sf.jasperreports.eclipse.viewer.ViewerCanvas.refresh(ViewerCanvas.java:344)
at net.sf.jasperreports.eclipse.viewer.ViewerCanvas$2.viewerStateChanged(ViewerCanvas.java:118)
at net.sf.jasperreports.eclipse.viewer.ReportViewer.fireViewerModelChanged(ReportViewer.java:383)
at net.sf.jasperreports.eclipse.viewer.ReportViewer.setPageIndex(ReportViewer.java:297)
at com.jaspersoft.studio.editor.preview.view.report.swt.SWTViewer.setJRPRint(SWTViewer.java:125)
at com.jaspersoft.studio.editor.preview.view.report.swt.SWTViewer.setJRPRint(SWTViewer.java:112)
at com.jaspersoft.studio.editor.preview.PreviewJRPrint.switchRightView(PreviewJRPrint.java:226)
at com.jaspersoft.studio.editor.preview.PreviewContainer.switchRightView(PreviewContainer.java:247)
at com.jaspersoft.studio.editor.preview.PreviewJRPrint$3.switchView(PreviewJRPrint.java:194)
at com.jaspersoft.studio.editor.preview.PreviewJRPrint$1.run(PreviewJRPrint.java:153)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4144)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3761)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at com.jaspersoft.studio.rcp.intro.Application.start(Application.java:97)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
Caused by: net.sf.jasperreports.engine.JRException: Image read failed.
at net.sf.jasperreports.engine.util.JRJdk14ImageReader.readImage(JRJdk14ImageReader.java:73)
at net.sf.jasperreports.engine.util.JRImageLoader.loadAwtImageFromBytes(JRImageLoader.java:167)
at net.sf.jasperreports.engine.JRImageRenderer.getImage(JRImageRenderer.java:407)
at net.sf.jasperreports.engine.JRImageRenderer.getDimension(JRImageRenderer.java:482)
at net.sf.jasperreports.engine.RenderableUtil.getOnErrorRendererForDimension(RenderableUtil.java:264)
at net.sf.jasperreports.engine.export.draw.ImageDrawer.draw(ImageDrawer.java:116)
at net.sf.jasperreports.engine.export.draw.PrintDrawVisitor.visit(PrintDrawVisitor.java:134)

但是,正如您所看到的,根本原因仍然来自JRJdk14ImageReader.java第73行。

Though, as you can see, the root cause still comes from JRJdk14ImageReader.java line 73.

其他一些可能有用的信息:

Some other information that might be useful:

数据作为LONG BINARY(使用Sybase)存储在数据库中。

图像是base64编码。

The data is stored in the database as a LONG BINARY (using Sybase).
The image is base64 encoded.

氏问题是阻止我完成我的项目,截止日期快到了。任何帮助都会很棒。

This issue is blocking me from finishing my project, with the deadline approaching pretty fast. Any help would be great.

编辑2:我将 Jaspersoft Studio 的版本从5.5更新到5.6,但这没有做任何事情。

EDIT 2: I updated my version of Jaspersoft Studio from 5.5 to 5.6, but that did nothing.

同样,对于表达式我试过javax.imageio.ImageIO.read($ F {Attr1_icon})
这实际上不会产生任何错误,但是图像是空白的。

As well, for the expression I tried javax.imageio.ImageIO.read($F{Attr1_icon}) This actually does not produce any error, but the image is blank.

推荐答案

即使我在问题中发布了它,我完全忽略了图像是Base64编码的事实,这意味着它是一个字符串。因此,Jasper无法使用此值,因此必须对其进行解码。这可以通过以下两种方式之一完成:

Even though I posted it in the issue, I completely overlooked the fact that the image was Base64 encoded, meaning it was a string. As is, this value couldn't be used by Jasper, so it had to be decoded. This can be done one of two ways:

将表达式更改为:

new java.io.ByteArrayInputStream(javax.xml.DatatypeConverter.parseBase64Binary($F{ImageField}))

或简单地将数据库中的字符串转换为二进制。在Sybase中,这是base64_decode函数。转换后,您只需将类型更改为java.io.InputStream就可以了。

or Simply convert the string to binary in the data base. In Sybase, that's the base64_decode function. Once it is converted, you can simply change the type to java.io.InputStream and it'll work.

这篇关于从数据库显示图像。获取net.sf.jasperreports.engine.JRException:图像读取失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆