Jump to content
We've recently updated our Privacy Statement, available here ×

Caching of images from DB BLOB


mreis

Recommended Posts

Hi,

 

we reference images in our jasper reports from database (stored in a blob column). Some of those images appear in the header and footer section of the report and are repeated/equal on every page of the resulting pdf. So we tried to enable the isUsingCache flag on the image, but without any luck (the image is still duplicated and the size of the resulting pdf unnecassarily huge).

Reading through "The definitive guide to JasperReports" on Caching Images (page 117/118, chap. 10) it says that caching is possible for java.io.InputStream.

The images in question are always the same on every rendered pdf page.

And here some snippets from the .jrxml file:

 <queryString><![CDATA[sELECT wblb_blob  logo FROM t_web_blob, t_stati where wblb_id = 6]]></queryString>

 <field name="LOGO" class="java.io.InputStream"/>

<image  scaleImage="FillFrame" isLazy="true" isUsingCache="true" ... >
     <reportElement mode="Opaque" x="369" y="19" width="199" height="83" forecolor="#000000" backcolor="#FFFFFF" key="logo"/>
     <box><topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
                <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
                <bottomPen lineWidth="0.0" lineColor="#000000"/>
                <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
     </box>
     <graphicElement stretchType="NoStretch" fill="Solid" />
     <imageExpression class="java.io.InputStream"><![CDATA[$F{LOGO}]]></imageExpression>
    </image>

Is it possible to enable/use caching for this kind of images?

 

kind regards & many thanks,

Markus

Link to comment
Share on other sites

  • 3 weeks later...
  • Replies 6
  • Created
  • Last Reply

Top Posters In This Topic

Hi,

 

You have to provide more details about your report.

Are subreports involved? Seeing the JRXML files would help.

 

I don't understand how you could display the logo in the page header while it is coming from a field.

If the data source moved to the next record, between the two pages, there will be a different input stream for the logo, and the image will not be cached.

 

Thank you,

Teodor

 

Link to comment
Share on other sites

Hi,

attached you can find two versions of the same jasper report - one defines a logo (fetched from a db blob) in the page header and the other one defines the same logo in the detail section. In both cases the resulting pdf (6 pages) doesn't cache the logo.

Hope this helps in answering the question.

kind regards & many thanks,

Markus

 

 

 

Link to comment
Share on other sites

Hi,

 

How many records is the query returning?

You say you have 6 pages. This means the query returns several records. In such case, the input stream field would have a different value for each record, so there is no way for the program to know it is actually the same image, but comming from different input streams.

 

In order for the caching to work, the image expression should evaluate to the exact same InputStream object. This does not happen in your case, because with each record, the result set will provide a different InputStream, even if you get the exact same picture. We do not make an analysis of the pixels in the image to realise it is the same. We are looking at objects.


Thanks,

Teodor

 

Link to comment
Share on other sites

Hi,

 

OK.

 

The next question would then be - How can we use image blobs in our reports using the caching mechanism? Do we need to use subreports which only contain the image based on a query that returns exactly one result (e.g.: SELECT image_blob FROM my_image_blob_table WHERE image_blob_id=1)? Given the requirement that caching for image blobs must work, can those subreports only be embedded in header or footer or could they also be embedded in the detail section?

 

Using image blobs from db is crucial for us, since we use the same reports in different environments on different servers and platforms, but all accessing the same database. If we'd use/embed images from the file system or via the classpath we'd have to duplicate the images which leads to a maintenance nightmare.

 

kind regards & many thanks,

Markus

Link to comment
Share on other sites

Hi,

 

There are various ways to do it, but I'll highlight only two of them.

 

You already mentioned subreports. Yes, but the log will not be in the subreport, but rather in the master report. You see, the master report should only have on record, and it should deal with the page headers and footers, where the same logo coming from a single InputStream would be put on all pages. Actually, I encourage you to declare the field as java.awt.Image and it would be loaded automatically for you. Then you could pass this image as a parameter to all subreports, if needed.

With the master having only one record, which deals with the logo, the actual content of the report has to be introduces by a subreport, which loops throught the detail records (has a different query). As mentioned above, the logo could be put in the detail as well, if you pass the image from the master as a parameter.

 

The second solution does not involve subreports, but rather query executers. You see, ideally, you should load the image from the database before launching the report. You should have it already loaded and available as a parameter for the report. And then the report is just a normal report that displays the parameter image in the headers or wherever it needs to.

If you don't have the opportunity to load the image before launching the report, you could create a custom query executer that extends the one existing in JR for SQL. In addition to running the report query, this custom query executer of yours would also execute a query to load the Logo, before the report query. Once loaded, the logo is deposited in a report parameter that the query executer declares. Check the query executers that exist in JasperReports and see how you could write one yourself. You would invent a query language to associate it with your query executer factory. Something like SQL-LOGO.

 

I hope this helps.
Teodor

 

Link to comment
Share on other sites

Hi,

 

I already tried "solution one" which is really simple and pragmatic and works great - unfortunately it is limited to one image/logo per master report ...

 

The second solution sounds very interesting, although there's the overhead costs in writing our own custom query executor. Still I think, that this may be a good solution and should help in other problem areas as well. Are there any other examples of custom query executors except from those already included in the jasperreports distribution?

 

Anyway - many thanks ... I think I have now a clear picture how caching works with blobs fetched from db and further I'll now investigate how query executors work and which benefits we can get from writing our own.

 

many thanks & kind regards,

Markus

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...