Basic works, Python fails same task. Exporting image fails for other resolutions. Why?

I am attempting to export Writer Pages as PNG in Python. For some reason only 96 DPI (approx) is working in python. When I change the resolution to higer values the image is still outputed at 96 DPI.

In basic changing the reslolution works. An example document is attached with both python and basic examples. The output images are saved in the same folder that the document exist in.

Am I doing something wrong in Python or is this a bug?

Python Code:

# coding: utf-8
from __future__ import unicode_literals
from pathlib import Path
import uno
from com.sun.star.beans import PropertyValue
from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS

CTX = uno.getComponentContext()
SM = CTX.getServiceManager()


def create_instance(name, with_context=False):
    if with_context:
        instance = SM.createInstanceWithContext(name, CTX)
    else:
        instance = SM.createInstance(name)
    return instance


def msgbox(message, title="LibreOffice", buttons=MSG_BUTTONS.BUTTONS_OK, type_msg="infobox"):
    toolkit = create_instance("com.sun.star.awt.Toolkit")
    parent = toolkit.getDesktopWindow()
    mb = toolkit.createMessageBox(parent, type_msg, buttons, title, str(message))
    return mb.execute()


def convert_writer_2_png():
    doc = XSCRIPTCONTEXT.getDocument()

    # 96 DPI
    # pixel_width = 793
    # pixel_height = 1122

    # 300 DPI
    pixel_width = 2481
    pixel_height = 3507

    # 600 DPI
    # pixel_width = 4962
    # pixel_height = 7014

    pv_width = PropertyValue()
    pv_width.Name = "PixelWidth"
    pv_width.Value = pixel_width

    pv_height = PropertyValue()
    pv_height.Name = "PixelHeight"
    pv_height.Value = pixel_height

    filter_data = (pv_width, pv_height)

    pv_name = PropertyValue()
    pv_name.Name = "FilterName"
    pv_name.Value = "writer_png_Export"

    pv_data = PropertyValue()
    pv_data.Name = "FilterData"
    pv_data.Value = filter_data

    props = (pv_name, pv_data)

    doc_path = Path(uno.fileUrlToSystemPath(doc.URL))

    controller = doc.getCurrentController()
    vc = controller.getViewCursor()
    vc.jumpToLastPage()

    for i in range(vc.getPage(), 0, -1):
        img_file_name = f"{doc_path.stem}_{i}.png"
        img_path = doc_path.parent / img_file_name
        url = uno.systemPathToFileUrl(str(img_path))
        doc.storeToURL(url, props)  # save PNG
        vc.jumpToPreviousPage()

    vc.jumpToFirstPage()

def export_via_python(*args):
    convert_writer_2_png()
    msgbox("Done!")

g_exportedScripts = (export_via_python,)

Basic Code:

Sub convertWriter2PNG()
    Dim   myViewCursor As Object
    Dim     myPageName As String, myString(255) As String, myFile As String, myFolder As String, myName As String
    Dim              i As Integer
    Dim   myPixelWidth As Long, myPixelHeight As Long

    Dim propsFiltre (1) As New com.sun.star.beans.PropertyValue
    Dim props       (1) As New com.sun.star.beans.PropertyValue

    myPageName = "_page_"

    ' Resolution choice (for an A4-Portrait document):
    myPixelWidth =  793 : myPixelHeight = 1122 '  96 DPI.
    ' myPixelWidth = 2481 : myPixelHeight = 3507 ' 300 DPI.
    ' myPixelWidth = 4962 : myPixelHeight = 7014 ' 600 DPI.

    propsFiltre(0).Name = "PixelWidth"  : propsFiltre(0).Value = myPixelWidth
    propsFiltre(1).Name = "PixelHeight" : propsFiltre(1).Value = myPixelHeight

    props      (0).Name = "FilterName"  : props      (0).Value = "writer_png_Export"
    props      (1).Name = "FilterData"  : props      (1).Value = propsFiltre()

    myString = split(thisComponent.url, "/") :           i = uBound(myString)
        myFile = myString(i)                   : myString(i) = ""
    myFolder = join (myString()       , "/")

    myString = split(           myFile, ".") :           i = uBound(myString)
                                            myString(i) = ""
    myName = join (myString()       , ".") :      myName = left(myName, len(myName) - 1)

    myViewCursor = thisComponent.CurrentController.ViewCursor
    myViewCursor.jumpToLastPage

    For i = myViewCursor.page to 1 step -1
        thisComponent.storeToURL(myFolder & myName & myPageName & Format(i, "000") & ".png", props())
        myViewCursor.jumpToPreviousPage 
    Next i

    myViewCursor.jumpToFirstPage : msgBox("Done!")
End Sub

writer_export_test.odt (83.3 KB)

It turns out that the way the properties were implemented was the issue.

Here is the updated working Python Macro.

# coding: utf-8
from __future__ import unicode_literals
from pathlib import Path
import uno
from com.sun.star.beans import PropertyValue
from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS
from com.sun.star.beans.PropertyState import DIRECT_VALUE  # type: ignore

CTX = uno.getComponentContext()
SM = CTX.getServiceManager()  # type: ignore

def prop_val(name, value):
    return PropertyValue(name, 0, value, DIRECT_VALUE)

def create_instance(name, with_context=False):
    if with_context:
        instance = SM.createInstanceWithContext(name, CTX)
    else:
        instance = SM.createInstance(name)
    return instance

def msgbox(message, title="LibreOffice", buttons=MSG_BUTTONS.BUTTONS_OK, type_msg="infobox"):
    toolkit = create_instance("com.sun.star.awt.Toolkit")
    parent = toolkit.getDesktopWindow()
    mb = toolkit.createMessageBox(parent, type_msg, buttons, title, str(message))
    return mb.execute()

def convert_writer_2_png():
    doc = XSCRIPTCONTEXT.getDocument()

    # 96 DPI
    # pixel_width = 793
    # pixel_height = 1122

    # 300 DPI
    pixel_width = 2481
    pixel_height = 3507

    # 600 DPI
    # pixel_width = 4962
    # pixel_height = 7014

    filter_data = (prop_val("PixelWidth", pixel_width), prop_val("PixelHeight", pixel_height))

    pv_name = prop_val("FilterName", "writer_png_Export")
    filter_data_propval = prop_val("FilterData", uno.Any("[]com.sun.star.beans.PropertyValue", filter_data))

    props = (pv_name, filter_data_propval)

    doc_path = Path(uno.fileUrlToSystemPath(doc.URL))

    controller = doc.getCurrentController()
    vc = controller.getViewCursor()

    vc.jumpToLastPage()

    for i in range(vc.getPage(), 0, -1):
        img_file_name = f"{doc_path.stem}_{i}.png"
        img_path = doc_path.parent / img_file_name
        url = uno.systemPathToFileUrl(str(img_path))
        doc.storeToURL(url, props)  # save PNG
        vc.jumpToPreviousPage()

    vc.jumpToFirstPage()

def export_via_python(*args):
    convert_writer_2_png()
    msgbox("Done!")

g_exportedScripts = (export_via_python,)