Вставить картинку по координатам на конкретной странице (writer).

Автор lutermaks, 16 августа 2024, 07:49

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

lutermaks

Перекопал наверное весь интернет.
Нашел, что можно вставить картинку по координатам в область draw page.
Определять страницы можно через видимый курсор контроллера, примеры методов:
boolean jumpToFirstPage()
 boolean jumpToLastPage()
 boolean jumpToPage( [in] long pageNo)
 long getPage()
 boolean jumpToNextPage()
 boolean jumpToPreviousPage()
 boolean jumpToEndOfPage()
 boolean jumpToStartOfPage()

Только не нашел ни одного примера, как вставить картинку по координатам на конкретную страницу.
Есть ли в области draw page понятие страниц?
Если я сделал переход на конкретную страницу через jumpToPage( [in] long pageNo), если я буду размещать картинку в draw page, то где картинка окажется? на первой странице или на той, что я указал?
Видимый курсор знает о страницах, но не имеет отношения к draw page.
Информации по работе с draw page также очень мало.
Может кто-то решал подобную задачу?

Нашел еще информацию, что в writer только одна страница в draw page.

mikekaganski

#1
Для начала определитесь, а к чему должна быть привязана картинка. Это картинка, привязанная к тексту (абзацу, символу) или к странице? Потому что привязанные к тексту объекты точно так же можно позиционировать по странице (привязка и позиционирование в определённой степени ортогональные понятия).

Чтобы позиционировать картинку, Вы задаёте ей свойства HoriOrient, HoriOrientRelation, HoriOrientPosition, VertOrient, VertOrientRelation, VertOrientPosition; причём HoriOrientPosition и VertOrientPosition относительно текущей страницы (если HoriOrientRelation и VertOrientRelation относятся к странице; HoriOrientPosition и VertOrientPosition - в 1/100 мм; для того чтобы они работали, HoriOrient и VertOrient должны быть com.sun.star.text.[Hori|Vert]Orientation.NONE). Текущая страница задаётся либо положением xRange, передаваемого в XText::insertTextContent (когда тип привязки - AT_PARAGRAPH, AS_CHARACTER, AT_FRAME или AT_CHARACTER), либо свойством AnchorPageNo (если тип привязки - AT_PAGE).

Вот код, вставляющий картинку на страницу 3, независимо от текущего положения курсора, на 11 см вправо от левой границы текста страницы, и на 12 см вниз от верха страницы целиком:

Function getGraphFromUrl(path_image)
  provider = CreateUnoService("com.sun.star.graphic.GraphicProvider")
  Dim props(0) as new com.sun.star.beans.PropertyValue
  props(0).Name  = "URL"
  props(0).Value = ConvertToURL(path_image)
  getGraphFromUrl = provider.queryGraphic(props())
End Function

Sub insert_image_on_page_3(path_image)
 doc = ThisComponent
 pos = doc.CurrentSelection.getByIndex(0).End

 image = doc.createInstance("com.sun.star.text.TextGraphicObject")
 image.Graphic = getGraphFromUrl(path_image)
 image.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PAGE
 image.AnchorPageNo = 3
 image.HoriOrient = com.sun.star.text.HoriOrientation.NONE
 image.HoriOrientRelation = com.sun.star.text.RelOrientation.PAGE_LEFT
 image.HoriOrientPosition = 11000
 image.VertOrient = com.sun.star.text.VertOrientation.NONE
 image.VertOrientRelation = com.sun.star.text.RelOrientation.PAGE_FRAME
 image.VertOrientPosition = 12000
 image.Width = 2500
 image.Height = 2500

 pos.Text.insertTextContent(pos, image, False)
End Sub
С уважением,
Михаил Каганский

bigor

lutermaks здравствуйте.
Проще всего в документе врайтер стоздать таблицу на нужном листе и уже в ячейки таблицы вставлять картинку
Поддержать наш форум можно здесь

lutermaks

Цитата: mikekaganski от 16 августа 2024, 09:33Для начала определитесь, а к чему должна быть привязана картинка. Это картинка, привязанная к тексту (абзацу, символу) или к странице? Потому что привязанные к тексту объекты точно так же можно позиционировать по странице (привязка и позиционирование в определённой степени ортогональные понятия).

Чтобы позиционировать картинку, Вы задаёте ей свойства HoriOrient, HoriOrientRelation, HoriOrientPosition, VertOrient, VertOrientRelation, VertOrientPosition; причём HoriOrientPosition и VertOrientPosition относительно текущей страницы (если HoriOrientRelation и VertOrientRelation относятся к странице; HoriOrientPosition и VertOrientPosition - в 1/100 мм; для того чтобы они работали, HoriOrient и VertOrient должны быть com.sun.star.text.[Hori|Vert]Orientation.NONE). Текущая страница задаётся либо положением xRange, передаваемого в XText::insertTextContent (когда тип привязки - AT_PARAGRAPH, AS_CHARACTER, AT_FRAME или AT_CHARACTER), либо свойством AnchorPageNo (если тип привязки - AT_PAGE).

Вот код, вставляющий картинку на страницу 3, независимо от текущего положения курсора, на 11 см вправо от левой границы текста страницы, и на 12 см вниз от верха страницы целиком:

Function getGraphFromUrl(path_image)
  provider = CreateUnoService("com.sun.star.graphic.GraphicProvider")
  Dim props(0) as new com.sun.star.beans.PropertyValue
  props(0).Name  = "URL"
  props(0).Value = ConvertToURL(path_image)
  getGraphFromUrl = provider.queryGraphic(props())
End Function

Sub insert_image_on_page_3(path_image)
 doc = ThisComponent
 pos = doc.CurrentSelection.getByIndex(0).End

 image = doc.createInstance("com.sun.star.text.TextGraphicObject")
 image.Graphic = getGraphFromUrl(path_image)
 image.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PAGE
 image.AnchorPageNo = 3
 image.HoriOrient = com.sun.star.text.HoriOrientation.NONE
 image.HoriOrientRelation = com.sun.star.text.RelOrientation.PAGE_LEFT
 image.HoriOrientPosition = 11000
 image.VertOrient = com.sun.star.text.VertOrientation.NONE
 image.VertOrientRelation = com.sun.star.text.RelOrientation.PAGE_FRAME
 image.VertOrientPosition = 12000
 image.Width = 2500
 image.Height = 2500

 pos.Text.insertTextContent(pos, image, False)
End Sub

Благодарю за помощь.
Можно спросить где нашли информацию? Или обнаружили экспериментальным путем?

mikekaganski

С уважением,
Михаил Каганский

lutermaks

Цитата: mikekaganski от 16 августа 2024, 16:45Посмотрел в исходном коде.

А можно Вас попросить указать путь к нужному файлу в репозитории.
Я склонировал к себе репозиторий core, в нем большое количество папок. Тут только методом тыка искать)

mikekaganski

Это проблематично, поскольку не такого одного файла. Мне понадобилось посмотреть достаточно много исходников, по пути поправить кое-что в документации и в wiki, чтобы разобраться в некоторых вопросах. Часть информации была написана мной ранее (wiki про позиционирование и привязку). Часть я вспомнил из предыдущих обсуждений (про то, что не нужно использовать свойство image.GraphicURL, из-за чего пришлось добавлять функцию getGraphFromUrl).

В общем, становитесь разработчиком ЛО, и тоже будете знать нужный файл в репозитории.
С уважением,
Михаил Каганский

sokol92

Владимир.

mikekaganski

С уважением,
Михаил Каганский

lutermaks

Цитата: mikekaganski от 16 августа 2024, 17:47Это проблематично, поскольку не такого одного файла. Мне понадобилось посмотреть достаточно много исходников, по пути поправить кое-что в документации и в wiki, чтобы разобраться в некоторых вопросах. Часть информации была написана мной ранее (wiki про позиционирование и привязку). Часть я вспомнил из предыдущих обсуждений (про то, что не нужно использовать свойство image.GraphicURL, из-за чего пришлось добавлять функцию getGraphFromUrl).

В общем, становитесь разработчиком ЛО, и тоже будете знать нужный файл в репозитории.

Можете еще подсказать как определить размеры текущей страницы?
И как можно определить границы содержимого документа ,чтобы установить настройки печати по этим границам (при конвертации форматов может не все содержимое переносить корректно из-за, например, слишком большой ширины документа) ?

lutermaks

Цитата: mikekaganski от 16 августа 2024, 09:33Для начала определитесь, а к чему должна быть привязана картинка. Это картинка, привязанная к тексту (абзацу, символу) или к странице? Потому что привязанные к тексту объекты точно так же можно позиционировать по странице (привязка и позиционирование в определённой степени ортогональные понятия).

Чтобы позиционировать картинку, Вы задаёте ей свойства HoriOrient, HoriOrientRelation, HoriOrientPosition, VertOrient, VertOrientRelation, VertOrientPosition; причём HoriOrientPosition и VertOrientPosition относительно текущей страницы (если HoriOrientRelation и VertOrientRelation относятся к странице; HoriOrientPosition и VertOrientPosition - в 1/100 мм; для того чтобы они работали, HoriOrient и VertOrient должны быть com.sun.star.text.[Hori|Vert]Orientation.NONE). Текущая страница задаётся либо положением xRange, передаваемого в XText::insertTextContent (когда тип привязки - AT_PARAGRAPH, AS_CHARACTER, AT_FRAME или AT_CHARACTER), либо свойством AnchorPageNo (если тип привязки - AT_PAGE).

Вот код, вставляющий картинку на страницу 3, независимо от текущего положения курсора, на 11 см вправо от левой границы текста страницы, и на 12 см вниз от верха страницы целиком:

Function getGraphFromUrl(path_image)
  provider = CreateUnoService("com.sun.star.graphic.GraphicProvider")
  Dim props(0) as new com.sun.star.beans.PropertyValue
  props(0).Name  = "URL"
  props(0).Value = ConvertToURL(path_image)
  getGraphFromUrl = provider.queryGraphic(props())
End Function

Sub insert_image_on_page_3(path_image)
 doc = ThisComponent
 pos = doc.CurrentSelection.getByIndex(0).End

 image = doc.createInstance("com.sun.star.text.TextGraphicObject")
 image.Graphic = getGraphFromUrl(path_image)
 image.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PAGE
 image.AnchorPageNo = 3
 image.HoriOrient = com.sun.star.text.HoriOrientation.NONE
 image.HoriOrientRelation = com.sun.star.text.RelOrientation.PAGE_LEFT
 image.HoriOrientPosition = 11000
 image.VertOrient = com.sun.star.text.VertOrientation.NONE
 image.VertOrientRelation = com.sun.star.text.RelOrientation.PAGE_FRAME
 image.VertOrientPosition = 12000
 image.Width = 2500
 image.Height = 2500

 pos.Text.insertTextContent(pos, image, False)
End Sub

Проверил пример кода, у меня якорь не устанавливается на конкретной странице с помощью AnchorPageNo, якорь устанавливается на первую страницу не в зависимости от координат X, Y.

mikekaganski

У Вас не пропечатались некоторые буквы. Например, во фразе "у меня в LibreOffice версии такой-то на операционной системе такой-то при выполнении конкретно такого-то кода (файл с макросом прикладываю; это точно тот код, а может быть, я немного его поменял) якорь устанавливается" (я выделил потерявшиеся буквы).
С уважением,
Михаил Каганский

lutermaks

Цитата: mikekaganski от 20 августа 2024, 16:11У Вас не пропечатались некоторые буквы. Например, во фразе "у меня в LibreOffice версии такой-то на операционной системе такой-то при выполнении конкретно такого-то кода (файл с макросом прикладываю; это точно тот код, а может быть, я немного его поменял) якорь устанавливается" (я выделил потерявшиеся буквы).
:) : извиняюсь
libreOffice 7.5.6.2
ОС: Win10 22H2
Использую код на python через UNO

import officehelper
import uno
import os
import argparse
from pythonscript import ScriptContext
from com.sun.star.awt import Size
from com.sun.star.beans import PropertyValue
from com.sun.star.text.TextContentAnchorType import AT_PAGE
from com.sun.star.text import HoriOrientation
from com.sun.star.text import VertOrientation
from com.sun.star.text import RelOrientation

def main():

    try:
        client = officehelper.bootstrap()     
    except Exception as error:
        print(error)

    args = parse_args()   

    insertImage(client, args.pathDocument, args.pathImage, args.X, args.Y, args.page)

def insertImage(client, pathDocument, pathImage, X, Y, page):

    # Получаем менеджер сервисов
    xMCF = client.getServiceManager()

    # Создаем сервис рабочего стола офиса в контексте текущего менеджера сервисов
    desktop = xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", client)
   
    # Загружаем файл документа в рабочий стол офиса
    uno_args = (createProp("Minimized", True),)
    docUrl = uno.systemPathToFileUrl(os.path.realpath(pathDocument))

    document = desktop.loadComponentFromURL(docUrl, "_default", 0, uno_args)

    # Загружаем в бинарный формат файл изображения
    path = os.path.realpath(pathImage)

    with open(path, "rb") as file:
        bytes = file.read()
   
    istream = xMCF.createInstanceWithContext("com.sun.star.io.SequenceInputStream", client)
    istream.initialize((uno.ByteSequence(bytes),))

    pos = document.CurrentSelection.getByIndex(0).End
    viewCursor = document.CurrentController.getViewCursor()
 
    image = document.createInstance('com.sun.star.text.TextGraphicObject')
    graphicprovider = xMCF.createInstanceWithContext("com.sun.star.graphic.GraphicProvider", client)
   
    istream_args = createProp("InputStream", istream)

    image.Graphic = graphicprovider.queryGraphic((istream_args,))
    image.AnchorType = AT_PAGE
    image.AnchorPageNo = page
    image.HoriOrient = HoriOrientation.NONE
    image.HoriOrientRelation = RelOrientation.PAGE_LEFT
    image.HoriOrientPosition = X
    image.VertOrient = VertOrientation.NONE
    image.VertOrientRelation = RelOrientation.PAGE_FRAME
    image.VertOrientPosition = Y   
    image.Width = 3500
    image.Height = 3500
   
    pos.Text.insertTextContent(pos, image, False)
    document.store()

    try:               
        document.close(False)
    except Exception:
        document.dispose()

def createProp(name, value):

    prop = PropertyValue()   
    prop.Name = name
    prop.Value = value

    return prop

def parse_args():

    parser = argparse.ArgumentParser()   
    parser.add_argument('-pathDocument', type=str, required=True, help='Путь к документу')
    parser.add_argument('-pathImage', type=str, required=True, help='Путь к картинке')     
    parser.add_argument('-X', type=int, help='Значение координаты по оси X (в мм)')
    parser.add_argument('-Y', type=int, help='Значение координаты по оси Y (в мм)')
    parser.add_argument('-page', type=int, help='Номер страницы куда необходимо установить картинку')
   
    return parser.parse_args()

if __name__ == "__main__":   
    main()

mikekaganski

Вы пробовали код Basic? Если что-то не работает, первый шаг - проверить точно так, как предложено. Потом уже можно по шагам проверять, на каком изменении сломается. (Я проверил: на 7.5 под Windows работает.)
С уважением,
Михаил Каганский

sokol92

Я проверял код Basic на знаменитой книге Питоньяка. Рисунок занимает предписанное ему место без всякого почтения к авторитету.  :)
Владимир.