Replies: 1 comment 3 replies
-
Thanks for the analysis. I agree that we should be more clear on how this is handled. Can you attach a report that exposes the problem? I am always confused by this until I start diving in again but IIRC, the DPI is not a property of the image (it just has a pixel width and height). It is a property of the medium on which the image is displayed. For example, to support new HiDPI displays, Eclipse started to deploy icons named [email protected], for example, copy.png and [email protected]. Based on the Display.getDPI routine, one or the other is rendered. If there is no such ..@2x icon, then the image is either automatically scaled up (leading to a fuzzy image), or it displays very tiny. Here is what looks to be a good source on DPI |
Beta Was this translation helpful? Give feedback.
-
Yesterday a customer who switched from BIRT 4.3.0 (with Java 6 or 8) to BIRT 4.10 (with Java 11) noticed that the sizing of a PNG background-image has changed dramatically when creating a PDF report.
So we have a regression.
The PNG image has a dpi value of 762, a pixel dimension of 4680 x 3267 Pixels and thus should have a physical size of 15.6 x 10.9 cm.
The PNG image is used as a background image in a table cell, the column is > 15.6 cm wide and its height is fixed as 10.9 cm.
With BIRT 4.3, it was rendered at the intended size.
With BIRT 4.10, the image is rendered much too big, so only a small part of the image is visible the remainder is cut off.
By using the debugger, I could see that many routines which calculate image sizes cannot detect the DPI resolution from the image's metadata and then set the DPI resolution to 96 as a last resort.
With BIRT 4.3, I cannot debug this, but because the resulting image has the intended size, I assume that either BIRT could detect the resolution from the PNG file, or BIRT shrinked the image (assuming 96dpi) because the row height is fixed.
Yesterday, I spent the whole day digging through the code and I have working proof-of-concept for a workaround using a UserProperty to overrride the calculated DPI value, which I probably will publish as a draft PR. This will allow us to restore BIRT 4.3's behavior regarding background image size.
But:
When I stepped through the code for image handling (actually, I only searched for handling of background images) in the debugger,
I observed the following:
context.getDpi()
or something similar is called, using some kind of logic.One example is
PropertyUtil.java
. Here we have methodsgetImageDpi
,getRenderDpi
,getScreenDpi
,getDimensionValue
.getImageDpi
is called from ImageAreaLayout.javagetSpecifiedDimension
.There are obviously different algorithms used to calculate image sizes and it seems that there is no documentation / specification available for a report developer how this is supposed to work.
After developing BIRT reports for >12 years, using images in BIRT is still trial and error for me.
The following variables may be part of the calculation:
I think the logic for the sizing of images needs to be written down somewhere in an understandable form.
And I think that BIRT's 4.3 behavior regarding the sizing of background images was better than the current implementation.
In my upcoming PR, I am using a User Property to override the DPI settings for individual elements, but I'm not sure if this is really necessary if we can define a set of simple rules which correspond roughly to the current implementation (except for the PDF background regression I mentioned at the top).
For example, these rules could be (just a very first proposal):
R1: BIRT does not use DPI resolution (or physical dimension) metadata from image files (including SVG files).
R2: To be defined: behavior of the HTML emitter if the image contains information mentioned in R1
R3: BIRT always uses the pixel dimensions (width and height in pixels) as a basis for size calculation for bitmap image formats (note that the DPI resolution is yet undefined).
R4: BIRT always uses the viewbox attribute to calculate the pixel size of an SVG file (this corresponds to R3).
SVGs without a viewbox are not supported.
R5: A DPI value is calculated as follows (the first value >0 wins):
R6: The "normal" physical dimensions are computed from the results of R4 and R5: width in inches = xPixels / dpi, height in inches = yPixels / dpi.
At this point, we know how big the image should normally be, but we also have a container with its own size contraints. So we may have to scale and crop the image now.
R7: For Image items:
The size of the area which actually can be used for the image is the inside the container's size minus padding and border.
To be defined...
R8: For background-images:
To be defined...
Beta Was this translation helpful? Give feedback.
All reactions