FOP и IKVM в.NET - изображения не работают

ОБНОВЛЕНИЕ 2: Я получил это работает полностью сейчас! Прокрутите вниз, чтобы узнать, как...
ОБНОВЛЕНИЕ: я получил это работает! Ну... частично. Прокрутите вниз для ответа...

Я пытаюсь заставить мой файл FO показывать внешнее изображение при преобразовании его в PDF (или RTF в этом отношении, но я не уверен, что RTF даже способны отображать изображения (они есть) с FOP, но я не могу заставить его работать. (Вопрос, заданный здесь, отличается от моего.)

Я использую IKVM 0.46.0.1 и скомпилировал dll FOP 1.0 для размещения в.NET; этот код работал нормально, когда я не пытался добавить изображения:

private void convertFoByMimetype(java.io.File fo, java.io.File outfile, string mimetype)
{
    OutputStream output = null;

    try
    {
        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
        // configure foUserAgent as desired

        // Setup outputput stream.  Note: Using BufferedOutputStream
        // for performance reasons (helpful with FileOutputStreams).
        output = new FileOutputStream(outfile);
        output = new BufferedOutputStream(output);

        // Construct fop with desired output format
        Fop fop = fopFactory.newFop(mimetype, foUserAgent, output);

        // Setup JAXP using identity transformer
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer(); // identity transformer

        // Setup input stream
        Source src = new StreamSource(fo);

        // Resulting SAX events (the generated FO) must be piped through to FOP
        Result res = new SAXResult(fop.getDefaultHandler());

        // Start XSLT transformation and FOP processing
        transformer.transform(src, res);
    }
    catch (Exception ex)
    ...
}

Однако, когда я (или, скорее, преобразование DocBook2FO) добавил следующий код:

<fo:external-graphic src="url(images/interface.png)" width="auto" height="auto" content-width="auto" content-height="auto" content-type="content-type:image/png"></fo:external-graphic>

в файл FO изображение не показывалось. Я прочитал немного FAQ на сайте Apache, где написано:

3.3. Почему моя графика не отображается?

Чаще всего внешний файл не обнаруживается FOP. Проверьте следующее:

Пустой или неправильный параметр baseDir.

Орфографические ошибки в имени файла (в том числе с использованием неправильного регистра).

...

Другие варианты, казалось, не были моим случаем (главным образом по причине ниже - "Странная Часть"). Я попробовал это:

...
try
{
    fopFactory.setBaseURL(fo.getParent());
    FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
    foUserAgent.setBaseURL(fo.getParent());
    FOURIResolver fourir = fopFactory.getFOURIResolver();
    foUserAgent.setURIResolver(fourir);
    // configure foUserAgent as desired
...

безрезультатно.

Странная часть

Когда я использую реализацию FOP из командной строки, она работает нормально и отображает мое изображение без проблем. (Я не хочу идти по пути run-command-line-from-program, потому что я не хочу заставлять пользователей устанавливать Java И.NET Framework, когда они хотят использовать мою программу.)
Файл png генерируется из GDI + из моего приложения (используя Bitmap.Save). Я также пробовал разные файлы png, но ни один из них не работал для меня.
Я могу что-то пропустить?

Спасибо большое за то, что так далеко

ОБНОВЛЕНИЕ и возможный ответ

Так что я мог бы понять, почему это не сработало. Я потратил некоторое время на изучение кода (прежде чем я просто копировал его, не задумываясь об этом). Проблема действительно в неправильных настройках.

Ключ находится в этом фрагменте кода:

    // Setup JAXP using identity transformer
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer(); // identity transformer

    // Setup input stream
    Source src = new StreamSource(fo);

    // Resulting SAX events (the generated FO) must be piped through to FOP
    Result res = new SAXResult(fop.getDefaultHandler());

    // Start XSLT transformation and FOP processing
    transformer.transform(src, res);

Здесь происходит преобразование идентичности, которое направляет свой собственный результат в экземпляр FOP, который я создал ранее. Это эффективно изменяет основание маршрутизируемого FO на исполняемый файл приложения. Мне еще предстоит выяснить, как сделать это без преобразования, и направить мой ввод непосредственно в FOP, но на данный момент я обошел это, скопировав мои изображения в каталог исполняемого файла.

Именно здесь возникла другая проблема. Теперь, когда я пытаюсь выполнить код, я получаю исключение в строке, которая говорит transformer.transform(src, res);, что сбивает с толку штаны из меня, потому что ничего не говорит. ExceptionHelper говорит:

java.lang.ExceptionInInitializerError был пойман

и нет внутреннего исключения или сообщения об исключении. Я знаю, что это трудно отладить только из того, что я написал, но я надеюсь, что это может быть легко исправить.

Кроме того, это электронное письмо кажется неопределенно связанным, но на него нет ответа.

UPDATE2

Наконец, после нескольких бессонных ночей мне удалось заставить его работать одним из самых простых способов.

Я обновил IKVM, скомпилировал fop с новой версией и заменил ссылки IKVM новыми dll. Ошибка больше не возникает, и мое изображение отображается нормально.

Я надеюсь, что это поможет кому-нибудь когда-нибудь

2 ответа

Решение

Вот сообщение, чтобы не оставлять вопрос без ответа, см. "Обновление 1" и "Обновление 2" в исходном сообщении для решения.

Я использую очень похожий код, хотя без FOUserAgent, Resolvers и т. Д., И он работает отлично.

Вы пытались установить src атрибут в XSLT без url() функционировать?

Что может помочь вам диагностировать проблему далее, это следующие утверждения:

java.lang.System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog")
java.lang.System.setErr(New java.io.PrintStream(New TraceStream(TraceStream.Level.Error)))
java.lang.System.setOut(New java.io.PrintStream(New TraceStream(TraceStream.Level.Info)))

куда TraceStream является реализацией.NET java.io.OutputStream который пишет в ваш любимый регистратор. Я разместил версию для Common.Logging пакет на http://pastebin.com/XH1Wg7jn.

Другие вопросы по тегам