Wie erreiche ich den Service "Canvas"?

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

preklov
***
Beiträge: 76
Registriert: Mo, 29.06.2009 09:04
Wohnort: Ruhrgebiet

Wie erreiche ich den Service "Canvas"?

Beitrag von preklov »

Um die Monitorauflösung zu ermitteln (s. viewtopic.php?f=18&t=66511), versuche ich bisher vergeblich, den API-Service com.sun.star.rendering.Canvas zu verwenden. Denn dessen Interface XCanvas bietet über die Methode getDevice() das Interface com.sun.star.rendering.XGraphicDevice.

Dessen Methoden getPhysicalResolution() und getPhysicalSize() scheinen mir genau das zu bieten, was ich suche.Wie aber komme ich dahin (der Einfachheit halber in Basic)?

Code: Alles auswählen

  oCanvas = createUnoService("com.sun.star.rendering.Canvas")
  oDevice = oCanvas.getDevice()
liefert die Fehlermeldung
Type:com.sun.star.lang.DisposedException
Message: PresenterCanvas object has already been disposed.
Alle meine Versuche, auf Frame-Windows oder DrawPages die Methoden getDevice() oder getCanvas() anzuwenden, führen zum "Eigenschaft oder Methode nicht gefunden"-Fehler.

Wer weiß was?

Schöne Grüße
Volker
Schöne Grüße
Volker
F3K Total
********
Beiträge: 3724
Registriert: Mo, 28.02.2011 17:49

Re: Wie erreiche ich den Service "Canvas"?

Beitrag von F3K Total »

Hi,
vielleicht hilft dies:

Code: Alles auswählen

Sub Main
    oDisplayAccess = CreateUnoService("com.sun.star.awt.DisplayAccess")
    oDisplay = oDisplayAccess.getByIndex(0)
    aWorkArea = oDisplay.WorkArea
    nWidht = aWorkArea.Width
    nHeight = aWorkArea.Height
    Print "Displaybreite = " & nWidht & " Displayhöhe = " & nHeight
    ScreenResX = nWidht/TWIPSPERPIXELX 'DPI
    Print "ScreenResX = " & ScreenResX &" dpi"
End Sub
Gruß R
preklov
***
Beiträge: 76
Registriert: Mo, 29.06.2009 09:04
Wohnort: Ruhrgebiet

Re: Wie erreiche ich den Service "Canvas"?

Beitrag von preklov »

Danke für den Versuch, F3K Total, aber das hilft mir nicht.

Wie du aus meinem Hinweis auf viewtopic.php?f=18&t=66511) ersehen kannst, will ich die API nutzen, um die Monitorauflösung auch in Python zu ermitteln. Das Interface XGraphicDevice bietet solche Methoden. Aber wie kann ich es nutzen?

Schöne Grüße
Volker
Schöne Grüße
Volker
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Wie erreiche ich den Service "Canvas"?

Beitrag von balu »

Hallo Volker,

ich antworte jetzt mal hier, anstatt in deinem anderen Thread.

F3K Total hat ja einen Beispielcode in Basic gezeigt, den ich mal eben angewendet habe.
Ergebnis:
Displaybreite = 1280 Displayhöhe = 738
ScreenResX = 85,33333333 dpi

Realität laut Einstellungen der "Eigenschaften von Anzeige" (WinXP)
1280 x 768 (30 mehr als der Basiccode zurückgibt)
DPI = 96 (ca. 10 dpi mehr)

Also irgendwie passt da noch etwas nicht so richtig. Nein F3K Total! Das liegt nicht an dir oder deinem Code. Das ist wohl mehr ein generelles Problem.


Volker, Du möchtest in Python eine systemunabhängige Abfrage erstellen. Nun, mit der Schlange kenne ich mich nicht aus. Aber wenn es schon zu Problemen unter StarBasic kommt, dann befürchte ich das es auch mit der Schlange welche geben wird. Das ist wohl meinerseits nicht bestätigt, aber irgendwie habe ich das so im Gefühl.

Ich stand selber mal vor einem ähnlichen Problem, Unterschiedliche Dialoggrößen zwischen Linux Systemen? Da ging es um Dialoge unter Windows erstellt, und dann unter Linux eingesetzt. Und wenn Du dir den verlinkten Thread in Ruhe durchliest, wirst Du da noch auf ein anderes Problem stoßen woran Du noch gar nicht gedacht hast, aber zum tragen kommen kann. Und ich sags dir gleich, wir konnten damals keine zufriedenstellende Lösung für mich finden.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
preklov
***
Beiträge: 76
Registriert: Mo, 29.06.2009 09:04
Wohnort: Ruhrgebiet

Re: Wie erreiche ich den Service "Canvas"?

Beitrag von preklov »

Hallo Balu,

die Geschichte mit den Größenunterschieden bei Dialogen ist schon erschreckend. Aber wenn man bedenkt, wie sehr dabei so unterschiedliche Faktoren wie Schriftarten und grafische Benutzeroberflächen und deren Grafikbibliotheken zusammenspielen, dann muss man vielleicht mit der Vielfalt leben.

Meine Problemstellung ist viel einfacher. Ich will die Bildinhalte aus Grafikdateien in odt-Dateien einbetten. Das ist vernünftigerweise nur möglich, wenn man ihre Ausdehnungen kennt. Ich kann mit der Methode queryGraphicDescriptor des Interface XGraphicProvider Informationen über die Grafik in einer Datei abfragen. Die stecken in den GraphicDescriptor-Eigenschaften Size100thMM resp. SizePixel. In png-Dateien beispielsweise sind Werte in Size100thMM und in SizePixel zu finden, in jpg-Dateien dagegen nur in SizePixel.

Wenn ich also jpg-Dateien finde, muss ich wissen, welchen Teil meines Bildschirms die Bilder einnehmen würden. Dazu benötige ich die Pixelausdehnungen. Mit den Basic-Funktionen TwipsPerPixelX und TwipsPerPixelY kein Problem. Naja, so lala.

Kleiner Ausflug in die konkrete Praxis: Mein Bildschirm hat laut Hersteller die Maße 518,4 x 324 mm. Ich betreibe ihn in einer Auflösung von 1920 x 1200 Pixeln. Pixelgröße laut Hersteller: 0,27 mm.

Die Ausgabe von xrandr im Terminal zeigt mir 519 x 324 mm, was praktisch der Herstellerangabe entspricht, auch die daraus berechnete Pixelgröße.

In Python kann ich die Tkinter-Bibliothek importieren (leider klappt das nicht innerhalb von AOO/LO). Mit deren Hilfe finde ich die abweichenden Maße 524 x 321 mm, mit den berechneten (unterschiedlichen) Pixelausdehnungen 0,2729 x 0,2675 mm, was immerhin gerundet noch den einheitlichen korrekten Wert 0,27 ergibt.

Die Pixelgröße von TwipsPerPixelX und TwipsPerPixelY allerdings ergibt jeweils 15, was 0,26 mm entspricht. Man kann auch damit leben, vor allem deshalb, weil die daraus berechnete Bildgröße etwas zu gering ausfällt - von Vorteil, wenn ein sehr großes Bild auf eine Writer-Seite passen soll, umgekehrt wäre es schlechter.


Sowohl die Anwendung als auch die Bilddarstellung finden auf demselben Bildschirm statt. Daran kann m.E. keine Grafikbibliothek und keine ma-Berechnung etwas ändern. Das sollte die Sache eigentlich einfach machen.

Zurück zu meinem Anliegen: Wie kann ich das Interface com.sun.star.rendering.XGraphicDevice einsetzen?

Schöne Grüße
Volker
Schöne Grüße
Volker
Karolus
********
Beiträge: 7533
Registriert: Mo, 02.01.2006 19:48

Re: Wie erreiche ich den Service "Canvas"?

Beitrag von Karolus »

Hallo

Möglicherweisse verstehe ich das Problem nicht, aber ursprünglich gehts dir doch darum Bilder einzufügen (in Writer?) und dabei Höhe und Breite in einem echten Längenmass auszulesen und zu setzen ??

Code: Alles auswählen

from com.sun.star.awt import Size
#from com.sun.star.awt import Point

def insert_image_writer():
    """
    Beispielscode um in Writer ein Bild einzufügen,
    mit Beschränkung auf die maximale Seitenbreite
    
    """
    
    doc = XSCRIPTCONTEXT.getDocument()
    page = doc.DrawPage
    grafic = doc.createInstance("com.sun.star.drawing.GraphicObjectShape")
    grafic.GraphicURL = 'file:///home/karolus/bilder/123.jpg' #anpassen
    page.add(grafic)
    dummysize = Size()
    dummysize.Width = 2000
    dummysize.Height = 1500
    grafic.setSize(dummysize) 
    #dummy-Werte setzen damit die folgenden Werte initialisiert werden 
    height = grafic.Graphic.Size100thMM.Height
    print(height)
    width = grafic.Graphic.Size100thMM.Width
    print(width)
    
    newsize = Size()
    max_width = 17000 #max bedruckbare Seitenbreite in 1/100mm bei DIN A4 Potrait

    newsize.Width = max_width
    # Höhe berechnen unter Berücksichtigung der originalen Seitenverhältnisse
    newsize.Height = height * max_width / width 
    print(newsize.Height)

    grafic.setSize( newsize )
    # Todo: grafic.setPosition( ...)
    # new_pos = Point()
    #new_pos.X = ...
    #new_pos.Y =,...
    #grafic.setPosition( new_pos )
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
preklov
***
Beiträge: 76
Registriert: Mo, 29.06.2009 09:04
Wohnort: Ruhrgebiet

Re: Wie erreiche ich den Service "Canvas"?

Beitrag von preklov »

Hallo Karolus,

dein Lösugsvorschlag hat mich umgehauen. Denn ich kannte ihn, habe ihn aber schon vor Jahren als untauglich verworfen und eine andere Lösung gesucht und bei Andrew Pitonyak gefunden. Ich wollte zuerst einfach mein Bedauern äußern, als ich doch erst noch den Test machte:
Es funktioniert. Ich staune.

Ich staune deshalb, weil es in Basic nicht funktioniert. Versuche einmal:

Code: Alles auswählen

Sub InsertImageWriter
  Dim oDoc
  Dim oPage
  Dim oGraphic
  Dim sPath As String
  Dim oDummysize As New com.sun.star.awt.Size
  Dim oNewsize As New com.sun.star.awt.Size
  Dim lHeight As Long
  Dim lWidth As Long
  Dim lMaxWidth As Long
  
  oDoc = ThisComponent
  oPage = oDoc.DrawPage
  oGraphic = oDoc.createInstance("com.sun.star.drawing.GraphicObjectShape")
  'sPath = "/home/volker/Bilder/StrandImAbendlicht.jpg"
  sPath = "/home/volker/Dokumente/55.90.png"
  oGraphic.GraphicURL = ConvertToURL(sPath)
  oPage.add(oGraphic)
  oDummysize.Width = 1500
  oDummysize.Height = 2000
  oGraphic.setSize(oDummysize)
  lHeight = oGraphic.Graphic.Size100thMM.Height
  Print "Höhe der Grafik: " & lHeight
  lWidth = oGraphic.Graphic.Size100thMM.Width
  Print "Breite der Grafik: " & lWidth
  lMaxWidth = 1700
  oNewsize.Width = lMaxWidth
  oNewsize.Height = lHeight * lMaxWidth / lWidth
  Print "Neue Höhe der Grafik: " &  oNewsize.Height
  
  oGraphic.setSize(oNewsize)
End Sub
Das Bild bleibt briefmarkenklein oben links kleben.

Was ist das? Der Basic-Code ist m.E. identisch mit dem Python-Code. Warum geht es in Python und nicht in Basic? Hast du eine Idee?

Das bedeutet nebenbei, dass ich den Code für meine spezielle Anwendung in Teilen neu strukturieren muss. Aber das ist zu verschmerzen.

Schöne Grüße
Volker
Schöne Grüße
Volker
Karolus
********
Beiträge: 7533
Registriert: Mo, 02.01.2006 19:48

Re: Wie erreiche ich den Service "Canvas"?

Beitrag von Karolus »

Hallo

Ich hab meinen Code von oben nch Basic übersetzt, und er liefert exakt das gleiche Ergebnis wie als Pythonfunction( getestet mit Libreoffice und Apache-office )



edit:
Es scheint am Dateiformat der Bilder zu liegen, .png und .gif liefern hier auch nicht das erhoffte Ergebnis.

bei .gif-Bildern scheint es zu klappen mit:

Code: Alles auswählen

.....
    height = grafic.Size.Height#grafic.Graphic.Size100thMM.Height #originale Werte    
    print(height)
    width = grafic.Size.Width #grafic.Graphic.Size100thMM.Width
    print(width)
 .....
 
die auskommetierten Teile gelten bei .jpg

Vielleicht schau ich mir das morgen nochmal genauer an...


edit2:
falls du viele Bilder auf diese Weise einfügen möchtest, wäre eventuell eine Umwandlung|Vorverarbeitung der Bilder per Batch sinnvoll -- schau dir mal Imagemagick an, dazu gibts auch eine Python-anbindung
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
preklov
***
Beiträge: 76
Registriert: Mo, 29.06.2009 09:04
Wohnort: Ruhrgebiet

Re: Wie erreiche ich den Service "Canvas"?

Beitrag von preklov »

Hallo Karolus,
falls du viele Bilder auf diese Weise einfügen möchtest, wäre eventuell eine Umwandlung|Vorverarbeitung der Bilder per Batch sinnvoll -- schau dir mal Imagemagick an, dazu gibts auch eine Python-anbindung
Werde ich mir einmal anschauen, welche Gestaltungsmöglichkeiten es da gibt.

Konkret geht es darum, inhaltlich zusammengehörende Bilddateien in pdf-Dateien zu packen, dabei aber zu beachten, dass sie möglichst die Größe beibehalten (also nur dann skaliert werden, wenn sie zu groß für DIN A4 sind), dass sie direkt lesbar sind (also Hochformat und Querformat beibehalten) und dass sie kompakt angeordnet sind (also so viele auf eine Seite gruppieren, wie darauf passen). Diese pdf-Dateien werden dann an Daten in einem Tabellenblatt verlinkt. Wenn Imagemagick im Zusammenspiel mit Python diese Layout-Aufgaben leisten kann, wäre das eine Alternative. So aber werden die Bilddateien sukzessive auf Zusammengehörigkeit zu einer Gruppe geprüft, als Gruppe in ein verborgenes Writer-Dokument gelegt und als PDF gespeichert, dann im Writer gelöscht, und so weiter mit der nächsten Gruppe. Zum Schluss wird das Writer-Dokument natürlich geschlossen :)

Daher war mein bisheriger Ansatz, die Grafikgröße vor dem Einbetten zu ermitteln, m.E. nicht so sehr von hinten in die Brust geschossen, denn die Layoutberechnungen sind in beiden Fällen die gleichen, egal ob ich die Größe vor oder nach dem Einbetten ermittele.

Ich bin nur gespannt, ob du herausfinden kannst, warum der Basic-Code bei jpg- und png-Dateien versagt.
Nachträglich: Geht bei mir auch nicht mit bmp- und svg-Dateien, und bei gif-Dateien sind Höhe und Breite = 0.

Schöne Grüße
Volker
Schöne Grüße
Volker
preklov
***
Beiträge: 76
Registriert: Mo, 29.06.2009 09:04
Wohnort: Ruhrgebiet

Re: Wie erreiche ich den Service "Canvas"?

Beitrag von preklov »

Für das Einfügen von Bildern, wie es mit Python problemlos funktioniert, scheint wohl keine schnelle Lösung mit Basic verfügbar zu sein. Ich werde mich bei Gelegenheit mal wieder darum kümmern, und da ich nun weiß, dass es mit Python keine Fehler gibt, kann ein Fehlerreport begründet sein.

Für alle, die eine funktionierende Ausweichlösung in Basic brauchen: Schaut hier mal rein:

Andrew Pitonyak: OpenOffice-Makros Erklärt, Kap. 14.3 Bilder, S. 372-374
https://www.uni-due.de/~abi070/ooo.html
Dort zum Download zwischen PDF und ODT wählen.

Schöne Grüße
Volker
Schöne Grüße
Volker
Antworten