#tdf51510: Change the DPI to get better resolution, but failed the unit test

Lodev lodev at ossii.com.tw
Fri Aug 18 14:01:12 UTC 2023


Hi, Tomaž,

Tomaž Vajngerl 於 2023/8/11 17:31 寫道:
> Hi,
>
> On Fri, Aug 11, 2023 at 8:06 AM Lodev<lodev at ossii.com.tw>  wrote:
>> Hi,
>>
>>
>> We're trying to fix #tdf51510: "Exporting documents with embedded SVG to
>> doc or docx converts the image to low-resolution pixel graphics" since
>> it bothers us and it seems more and more bugs duplicated or related to
>> this one.  We changed in vcl/source/gdi/vectorgraphicdata.cxx:78
>>
>> -            Size
>> aDPI(Application::GetDefaultDevice()->LogicToPixel(Size(1, 1),
>> MapMode(MapUnit::MapInch)));
>> +            Size
>> aDPI(Application::GetDefaultDevice()->LogicToPixel(Size(50, 50),
>> MapMode(MapUnit::MapInch)));
>>
>> To get better resolutions.  It worked.  Exported docx file with embedded
>> png now gets better resolution.
>>
>> However this change couldn't pass unit test :
>> sw/qa/extras/ooxmlexport/ooxmlexport16.cxx:762, tdf136841.docx . It
>> seems to be fixed, expecting low resolution converted images.
>>
>> Since it didn't pass the unit test, we didn't commit the patch to
>> gerrit.  So here, first we'd like to know if this solution, changing
>> size(1,1) to size(50,50) is acceptable or not?
> I wouldn't do it like that. The purpose of that LogicToPixel
> conversion is to figure out the DPI (number of pixels/inch) of the
> output device - changing that to 50 doesn't make sense considering
> what that call tries to achieve (you ask what's the number of pixels
> per 50inches).
> The next issue is that this will result in a 50x bigger size - that's
> a lot! Typically the device DPI is 96 - this makes it 50*96 = 4800,
> which means a 3 x 3 inch image (not that A4 paper size is 8.3 x 11.7
> inch, so 3x3 inch image is typical) will have the resolution of
> 14400x14400 pixels!
> Note also that in ODF we store a PNG bitmap for vector images in
> addition the the vector image, which serves as a fall-back. For that
> we go through the same code path, so the file size would increase
> significantly.
>
> What I suggest is to not depend on the output device DPI (which causes
> us a lot of trouble because the result then depends on the system and
> OS) and set a constant but high enough DPI, that will be good enough
> in most cases. 300DPI is usually good enough for printing so I think
> that would be a good constant to use here (it's 3x bigger than typical
> 96DPI of an output device).
>
> Tomaž

In fact, when we were doing more test, we found the behavior somewhat 
strange.

We used attachment 170646 in tdf#51510.

vcl/source/gdi/vectorgraphicdata.cxx, line 77:

             // get system DPI
             Size 
aDPI(Application::GetDefaultDevice()->LogicToPixel(Size(1, 1), 
MapMode(MapUnit::MapInch)));
             if (rTargetDPI.has_value())
             {
                 aDPI = *rTargetDPI;
             }

             const uno::Reference< rendering::XBitmap > xBitmap(
                 xPrimitive2DRenderer->rasterize(
                     comphelper::containerToSequence(rSequence),
                     aViewParameters,
                     aDPI.getWidth(),
                     aDPI.getHeight(),
                     aRealRect,
                     nMaximumQuadraticPixels));

First, Size aDPI: 
Application::GetDefaultDevice()->LogicToPixel(Size(1,1), 
MapMode(MapUnit::MapInch)), here we did get aDPI is (96, 96).

However, after saving as docx, the PNG image information (in Compress 
Image dialog) we got is:

Actual dimensions: 0.21"x0.21" (21x21 px)

Apparent dimensions: 4.24" x 4.24" at 4 DPI

If we set LogicToPixel(Size(4,4), ...), we got:

Actual dimensions: 0.84"x0.84" (84x84 px)

Apparent dimensions: 4.24" x 4.24" at 19 DPI

Second, We then tried to directly assign 300DPI by adding

aDPI.setWidth(300);

aDPI.setHeight(300);

before calling xBitmap(xPrimitive2DRenderer0>rasterize()).  We printed 
aDPI.getWidth() and aDPI.getHeight() and did got 300, 300.

However the PNG image information saved in docx file

Actual dimensions: 0.68 x 0.68 (66x66 px)

Apparent dimensions: 4.24" x 4.24" at 15 DPI

Is the above way to correctly "set a constant but high enough DPI"?  But 
even if I assigned 300DPI the result DPI is still very low.  So, what is 
the exactly way to set constant 300DPI?

BTW, the rTargetDPI was a parameter of 
convertPrimitive2DSequenceToBitmapEx, which  was called only once and 
the parameter rTargetDPI was never used.

That is, it is always nullptr by default, according to its declaration.  
This parameter seems to be useless at all.


Any suggestion will be appreciated.


Thanks for your help.

Dev


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/libreoffice/attachments/20230818/c9315a0f/attachment.htm>


More information about the LibreOffice mailing list