Das Notes Forum
Lotus Notes / Domino Sonstiges => Java und .NET mit Notes/Domino => Thema gestartet von: grandmetre am 15.04.08 - 11:21:19
-
Hallo zusammen,
Ich erstelle momentan eine pdf-Datei mit dem Inhalt des Bodys meiner Dokumente. Jetzt möchte ich auch noch die dort integrierten Bilder in die Datei einfügen. Mein Problem ist, dass ich nicht an die in den Body integrierten jpegs dran komme. Ich habe schon mit diversen Arten herumprobiert, EmbeddedObjects zu erhalten habe aber nicht den kleinsten Ansatz, wie ich an die Bilder komme. Vielleicht habe ich auch den falschen Ansatz gewählt, weil ich mich nur wenig mit der Struktur von RichTextItems auskenne. Bis jetzt habe ich es mit dem RichTextNavigator methoden getFirstElement() und getNextElement() versucht. Nur da weiß ich nicht, welchen typ ich nehmen muss.
Kann mir da jemand helfen?
-
über einen DXL-Export und auswerten des Streams kommt man an einen Base64 kodierten Stream, der die Bildinformationen enthällt. Diesen Base64 kodierten Stream kann man mit der NotesMime-Klasse wieder in einen binären Stream dekodieren.
-
Und wie mache ich das? Ich finde weder eine Methode, die mir einen solchen Stream liefert noch eine NotesMime-Klasse.
-
in der Klasse DXLExporter gibt es die Methode ExportDXL, damit kannst Du ein Dokument exportieren. Mit dem DOM/SAX-Parser kommst Du dann an die entsprechenden Elemente heran. Dieser Tag nennt sich "picture".
Die Klasse zum Dekodieren im Java ist die MIMEEntity-Klasse und nicht die LS-Klasse NotesMIMEEntity.
Du erzeugst ein neues Dokument in der DB, erzeugst in dem Dokument eine MimeEntity mit der Methode CreateMIMEEntity, schreibst mit der Methode SetContentFromText den String aus dem DXL-Stream rein und liest mit der Methode GetContentAsBytes den Binärstream wieder heraus.
-
Zur Inspiration wie man diese ganzen Notes-XML Parser Klassen an den Start kriegt empfehle ich DRINGEND den source code von Viewnify von Martin Vereecken auf openNTF. Dieses sogenannte Pipeline Architektur ist wirklich nicht einfach, v.a. wenn du ein NotesDOMParser Objekts einhängst.
-
So, ich hab mal ein wenig rumprobiert bekomme aber leider keine Daten in meine jpeg-datei, die aber trotzdem angelegt wird. Hier der code:
public static void decodeImageString(String imageString){
try{
NotesThread.sinitThread();
Database database = persistence.getOpenDatabase(dbFileName, server, session);
Document doc = database.createDocument();
MIMEEntity entity = doc.createMIMEEntity();
Stream stream = session.createStream();
entity.setContentFromText(stream, "jpeg", MIMEEntity.ENC_BASE64);
stream.writeText(imageString);
stream.close();
Stream imageStream = session.createStream();
entity.getContentAsBytes(imageStream);
FileOutputStream os = new FileOutputStream("C:\\temp\\test\\test.jpg");
os.write(imageStream.read());
os.flush();
os.close();
}
catch (Exception e){
e.printStackTrace();
}
}
Kann mir einer dagen, wo der Fehler liegt?
-
Du musst dir glaub ich - wie Diali gesagt hat - den entsprechenden base-64 encodedeten Bereich aus XML-Repräsentation eines NotesDokuments mit Bild herausparsen und das dann mit der MimeEntity Klasse dekodieren.
-
Das ist genau das, was ich in diesem Teil meines codes versuche. Der String "imageString" ist genau dieser Bereich der XML. Das hab ich schon getestet und für Gut befunden. Mein Problem im Moment ist, dass ich nicht weiß, wie die Methoden, die ich benutzt habe, genau zu handhaben sind, da die Doc nicht sehr aussagekräftig ist.
-
Du schliesst vermutlich den stream zu früh.
Die Zeile als letzte im try-block:
-
Ich habe es hiermit versucht:
try{
NotesThread.sinitThread();
Database database = persistence.getOpenDatabase(dbFileName, server, session);
Document doc = database.createDocument();
MIMEEntity entity = doc.createMIMEEntity();
Stream stream = session.createStream();
entity.setContentFromText(stream, "jpeg", MIMEEntity.ENC_BASE64);
entity.decodeContent();
stream.writeText(imageString);
Stream imageStream = session.createStream();
FileOutputStream os = new FileOutputStream("C:\\temp\\test\\test.jpg");
entity.getContentAsBytes(imageStream);
byte[] c;
while ((c = imageStream.read()).length > 1){
os.write(c);
}
os.flush();
os.close();
stream.close();
}
catch (Exception e){
e.printStackTrace();
}
und habe beim debuggen festgestellt, dass die .read-Methode des imageStreams auch beim ersten lesen schon von der Länge "0" ist. Also muss vorher schon mal was schief gelaufen sein. Auch mit "entity.getReader()" habe ich es versucht. Bin aber auch daran gescheitert, da der Reader null war.
-
Ich habe jetzt zwar wenig Erfahrung in dem Gebiet, aber ich halte für den Weg über das Notes Mimeentity eher für eine schwache Lösung. Warum nicht die Konvertierung von Base64 in Binary in Java machen.
Hier mal ein Link auf einen Sourcecode auf ein Tool, dass Base64 encoden und decoden kann.
http://ostermiller.org/utils/Base64.java.html
Eventuell kann man daraus die vorgehendsweise erkennen und für sein eigenens Programm umsetzen.
Grüße
Ralf
-
Du erzeugst ja auch ein ganz neues Dokument. Da kann ja auch gar nichts drin stehen!
Ich würd ein existierendes Notes Dokument parsen, in dem schon ein Bild eingebunden ist.
-
Wenig Zeit und darüber hinaus eine sich aufbauende Erkältung. Vielleicht wird das morgen in beider Hinsicht besser (Zeit + Fitness).
Paßt thematisch gut in das Notes-Zeugs, das ich mache.
Im Gegenteil zu Ralf finde ich
entity.setContentFromText(stream, "jpeg", MIMEEntity.ENC_BASE64);
absolut ok. Schön kompakt.
Hab aber das Gefühl, du, grandmetre, hast ein paar Sachen in DXL noch nicht klar. Wenn da wirklich kein File drin ist, gibts in der DXL-Repräsentation auch keine Node.
Gruß Axel
-
das Decodieren über die Klasse MimeEntity ist um einiges performanter als alles was ich bisher gesehen habe an selbstgeschriebenen Decodierungs-/Codierungs-Werkzeugen. Interessant wird dies wahrscheinlich erst, wenn es um eine Stapelverarbeitung geht.
-
So, Ich habe jetzt den String mit Base64 konvertiert. Jetzt stellt sich nur noch die Frage, wie ich daraus ein Image erstelle. Mein momentander Ansatz lautet:
SinglePixelPackedSampleModel erstellen und mit setPixel(s) füllen. Damit ein Raster Object anlegen mit dem man dann ein BufferedImage mit der setData(Raster r)-Methode füllen kann.
Ich find die ganze Sache ein wenig umständlich. Gibt es vielleicht einfachere Lösungen zu der Sache?
-
generate jpeg Java gibt eine Menge Treffer in google.
-
So, hat zwar etwas gedauert aber das Ziel ist erreicht :-)
Zur Lösung gehörten zwei grundlegende Sachen:
1.) Ahnung vom Parsen von XML-Dateien zu haben und
2.) den Richtigen Base64 decoder benutzen
ad 1)
Ich habe mich im Nachhinein gegen den SAX- und für den DOM-Parser von java entschieden. Der SAX-Parser ist zwar einfacher zu handhaben, wenn es ums reine Auslesen geht liefert aber nicht den originalen String zurück, zumindest wenn man es so wie ich macht und nur über den Handler geht. Der DOM-Parser ist zwar ein wenig umständlich, aber wenn man weiß, wie man an die Unterelemente kommt nur ein wenig Schreibarbeit um an den Original-String zu gelangen.
ad 2)
Die Versuche mit der hier vorgeschlagenen MIMEEntity Klasse zu arbeiten habe ich schnell verworfen, da ich nicht wusste, wie man diese genau einzusetzen hat, da ich keine brauchbare Dokumentation gefunden habe. Danach versuchte ich es mit dem Base64 Klasse von Ostermiller und musste nach einigen Versuchen feststellen, dass einzelne bytes (Vergleich mit dem Editor) unterschiedlich zu sein schienen. Zu guter letzt (ich zähle jetzt nicht alle auf) fand ich den sun.misc.BASE64Decoder (der von anfang an zur java-api gehört "arg").
Der Rest war einfacher als ich zuerst dachte. Einfach einen FileOutputStream instanziieren, das aus der BASE64Decoder.decodeBuffer(String input) methode gewonnene byte[] hineingeben, stream schließen, ende.
Ich hoffe, das ich mit dieser kurzen Ausführung jemandem helfen kann, dem ich das mühsälige ausprobieren ersparen möchte.
-
Glückwunsch.
Man kann mit einem SAX Parser jedes Element von jedem XML Dokument auslesen. Du hast ihn vermutlich nicht ganz richtig verwendet.
Das Problem mit DOM-Parsing ist aus meiner Sicht weniger, dass es mühsamer ist sondern eher, dass es sehr viel Ressourcen beansprucht, da das ganze xml Dokument in Speicher geladen wird und es dazu tendiert, unübersichtlichen Code zu erzeugen.
In Java für Notes präferiere ich inzwischen JDom oder XOM, weil das noch übersichtlicheren Code erzeugt.
Gruß Axel