FOP и IKVM в .NET - изображения не работают - PullRequest
1 голос
/ 06 сентября 2011

ОБНОВЛЕНИЕ 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, но ни один из них не работал для меня.
Я могу что-то пропустить?

Спасибо большое за то, что вы продвинулись

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

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

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

    // 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, но на данный момент я обошел это, скопировав мои изображения в каталог исполняемого файла.

Именно здесь возникла другая проблема. Теперь, когда я пытаюсь выполнить код, в строке появляется сообщение «1064 *», которое сбивает меня с толку, потому что оно ничего не говорит. ExceptionHelper говорит:

java.lang.ExceptionInInitializerError было обнаружено

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

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

UPDATE2

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

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

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

Ответы [ 2 ]

2 голосов
/ 13 сентября 2011

Я использую очень похожий код, хотя без 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.

0 голосов
/ 05 октября 2011

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

...