Как разпознать рисунок в файле Writer [Решено]

Автор Massaraksh7, 28 ноября 2024, 15:13

0 Пользователи и 1 гость просматривают эту тему.

Massaraksh7

Начал писать вот такой скрипт, который будет читать отдельные блоки из .odt-файла, и переводить их в .htm (см. вложение)
С текстом и стилями всё получается, а вот как распознать картинку, имея в виду не только её саму, но и в каком месте текста она находится. Все картинки будут "без обтекания" и формата только "png", если это важно.
Скрипт не будет универсальным и предназначен для узких целей.


Massaraksh7

Как найти картинки, я нашёл:
sub getallpictures
picts = ThisComponent.getGraphicObjects
    For i = 0 to picts.Count-1
       pict = picts.getByIndex(i)
       grf = pict.graphic
       .................???
     next i
end sub
Осталось понять, где они расположены (между какими параграфами), и сохранить их на диск. Тут пока не знаю.

Massaraksh7

И даже придумал, как сохранить на диск (знаю, что коряво, но, может, кто подскажет лучше).
sub getallpictures
picts = ThisComponent.getGraphicObjects
For i = 0 to picts.Count-1
   pict = picts.getByIndex(i)
   gr = pict.graphic
   bmp = gr.dib
   hi = UBound(bmp)
   oUcb = createUnoService("com.sun.star.ucb.SimpleFileAccess")       
   oOutputStream = createUnoService("com.sun.star.io.DataOutputStream") 
   oOutputStream.setOutputStream(oUcb.OpenFileWrite(ConvertToURL("C:\112.bmp")))
   for j=0 to hi
      oOutputStream.WriteByte(bmp(j))
   next j
   oOutputStream.closeOutput()
next i
end sub
Осталось зафиксировать их местоположение.

sokol92

Добрый день!

Штатное средство для работы с объектами, имеющими интерфейс XGraphic, - сервис GraphicProvider.

Вот пример, аналогичный Вашему, для Calc.
Владимир.

Massaraksh7

Спасибо!
Теперь ясно, как сохранять графику, но не вполне ясно про якоря. Точнее, в Calc-то ясно, а вот в Writer - нет. По идее, там аналогично, должен при выполнении
oPara=oShape.anchor должен получаться параграф, но чем он идентифицируется? Как узнать, что это N-тый параграф от начала? Текст сравнивать? Несистемно.

Massaraksh7

Ну, в общем-то, и с привязкой проблему решил.
sub wshapes
 Doc = ThisComponent
 Shapes = Doc.getDrawPage()
 for i = 0 to Shapes.count - 1
     oshape = Shapes(i)
     anch = oshape.anchor
     cursor = ThisComponent.getText().createTextCursorByRange(anch)
     cursor.goLeft(1,False)
     cursor.string="<img src=""c:\pict" & i & ".png"">"
 next i

sokol92

Для будущих читателей темы.

Для текстовых документов метод getAnchor возвращает объект, который поддерживает сервис TextRange. Этот сервис и "указывает на последовательность символов в Text".

Если два объекта TextRange указывают на один и тот же текст, то их позиции начала и конца можно сравнить с помощью методов интерфейса text.XTextRangeCompare. Примеры есть в известной книге Питоньяка.
Владимир.

Massaraksh7

Выложу тогда здесь окончательный вариант теста скрипта. (.Htm-файл и картинки создаются в каталоге "C:\Htm\")
Макрос - styletest

Massaraksh7

Цитата: Massaraksh7 от 30 ноября 2024, 16:45окончательный вариант
Нет. Ещё таблицы могут быть, надо обработать. И по мелочи подправил. Макрос Testhtml

sokol92

Цитата: Massaraksh7 от  2 декабря 2024, 12:55Ещё таблицы могут быть, надо обработать.
Цикл по ячейкам текстовой таблицы лучше выполнять c использованием getCellNames - см. раздел "14.9.3. Simple and complex tables" и макрос в нем книги Питоньяка OOME_4_1.odt.
Владимир.

Massaraksh7

#10
Цитата: sokol92 от  2 декабря 2024, 15:23Цикл по ячейкам текстовой таблицы лучше выполнять c использованием getCellNames
В данном случае - не уверен, что это правильно. Таблица в Html строится строго по столбцам, затем строкам, одна ячейка за другой. А в каком порядке мне выдаст getCellNames - я не знаю. Впрочем, ещё поэкспериментирую. Тем более, одно из требований к таблице - отсутствие объединённых ячеек.

Massaraksh7

Проверил на "взрослом" документе. Сразу вылезли недочёты. Во-первых, шейпы бывают не только графические, так что вставил проверку supportsService, во-вторых, разные картинки требуют разного масштабирования (потом этим займусь), ну, и, опять же, по мелочи там.

Massaraksh7

А вот сейчас столнкулся с необъяснимой вещью: на определённых документах отдельные параграфы удваиваются. Причём, посмотрел, где: цикл
While ParaEnum.hasMoreElements()
   Para = ParaEnum.nextElement()
   ...
wend
повторно выдаёт один и тот же параграф!
Пример - в приложении, выбросил из него всё лишнее.

Massaraksh7


mikekaganski

В документе 14 абзацев. Тело цикла работает 14 раз.
С уважением,
Михаил Каганский