[Solved] Save a draw shape as DIB bitmap?

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: [Solved] Save a draw shape as DIB bitmap?

Post by _savage »

Thank you, musikai! I think some of the code in your answer is very similar to your previous answer above.

Regarding the OriginURL property, it’s an empty string for all embedded images in different documents that I’ve tried. Furthermore, accessing DocumentStorage.getByName("Pictures") seems to work only for ODT files, other files with a different internal structure (e.g. DOCX) don’t have that property name. And lastly, for an ODT file with the following stored images

Code: Select all

('1000000000000100000001006DD65086A312ABA8.png', '1000020100000190000001904A733E71D6A24595.png', '10000000000000B4000000B4A976F024B23F98C8.jpg')
I still was unable to connect that stored file name with the DOM object—neither OriginURL nor Name seemed to contain useful information. Perhaps there’s another mapping from Name to the stored file name, but I couldn’t find that.

And so, after tinkering for a while I’ve decided that exporting a shape/image object as PNG is probably the best option at this point. Maybe in a spare moment later this week I’ll poke around some more, though…
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
musikai
Volunteer
Posts: 294
Joined: Wed Nov 11, 2015 12:19 am

Re: [Solved] Save a draw shape as DIB bitmap?

Post by musikai »

if anybody finds the connection between the image object and the embedded file in LO6.1 and higher please tell us.
Win7 Pro, Lubuntu 15.10, LO 4.4.7, OO 4.1.3
Free Project: LibreOffice Songbook Architect (LOSA)
http://struckkai.blogspot.de/2015/04/li ... itect.html
hubert lambert
Posts: 145
Joined: Mon Jun 13, 2016 10:50 am

Re: [Solved] Save a draw shape as DIB bitmap?

Post by hubert lambert »

Hi,

It no longer seems possible. See comment #4 and #5 here.
If this can be helpful, here is a python macro that returns the internal file of a XGraphic object inside a given document model:

Code: Select all

def findinternalimagefromxgraphic(thisgraphic, doc):
    ctx = XSCRIPTCONTEXT.getComponentContext()
    createunoservice = ctx.ServiceManager.createInstance
    pictures = doc.DocumentStorage.Pictures.ElementNames
    graphicprovider = createunoservice("com.sun.star.graphic.GraphicProvider")
    tddc = createunoservice("com.sun.star.frame.TransientDocumentsDocumentContentFactory")
    content = tddc.createDocumentContent(doc)
    cid = content.getIdentifier().ContentIdentifier
    props = (PropertyValue("URL", 0, "", 0),)
    for picture in pictures:
        props[0].Value = "{}/Pictures/{}".format(cid, picture)
        thatgraphic = graphicprovider.queryGraphic(props)
        if thatgraphic.MimeType == thisgraphic.MimeType:
            if thatgraphic.MaskDIB and thatgraphic.MaskDIB == thisgraphic.MaskDIB:
                return(picture)
            elif thatgraphic.DIB == thisgraphic.DIB:
                return(picture)
            elif thatgraphic.DIB[:5000] == thisgraphic.DIB[:5000]:
                return(picture)
    return "" 
Regards.
Attachments
find internal image.odt
(83.28 KiB) Downloaded 188 times
AOOo 4.1.2 on Win7 | LibreOffice on various Linux systems
musikai
Volunteer
Posts: 294
Joined: Wed Nov 11, 2015 12:19 am

Re: [Solved] Save a draw shape as DIB bitmap?

Post by musikai »

That is fantastic! I think this does exactly what is needed.

I would like to use this code to make the extension "PicExtract" compatible with LO6.1+ and tried to translate it into BASIC but am stuck at

Code: Select all

props[0].Value = "{}/Pictures/{}".format(cid, picture)
and expect also problems with

Code: Select all

thatgraphic.DIB[:5000] == thisgraphic.DIB[:5000]:
Would be great to have the (full) code in BASIC. :D
Until now I only created extensions with Basic.

äh, here is what I got so far:

Code: Select all

sub findinternalimagefromxgraphic(thisgraphic, doc)
    pictures = doc.DocumentStorage.Pictures.ElementNames
    graphicprovider = createunoservice("com.sun.star.graphic.GraphicProvider")
    tddc = createunoservice("com.sun.star.frame.TransientDocumentsDocumentContentFactory")
    content = tddc.createDocumentContent(doc)
    cid = content.getIdentifier().ContentIdentifier
      Dim props(1)as new com.sun.star.beans.PropertyValue 
  props(0).Name  = "URL" 
  props(0).Value = 0 'converttoURL(sFileUrl)
  props(1).Name  = "" 
  props(1).Value = 0
   rem props = PropertyValue("URL", 0, "", 0)
    findinternalimagefromxgraphic = ""
    for each picture in pictures:
        props(0).Value = converttourl("/Pictures/" & picture)'"{}/Pictures/{}".format(cid, picture)
        thatgraphic = graphicprovider.queryGraphic(props)
        if thatgraphic.MimeType = thisgraphic.MimeType then
            if thatgraphic.MaskDIB and thatgraphic.MaskDIB = thisgraphic.MaskDIB then
                findinternalimagefromxgraphic = picture
                exit for
            elseif thatgraphic.DIB = thisgraphic.DIB then
                findinternalimagefromxgraphic = picture
                exit for
            elseif thatgraphic.DIB(5000) = thisgraphic.DIB(5000) then
                findinternalimagefromxgraphic = picture
                exit for
            end if
        end if
   next
   
end sub
Win7 Pro, Lubuntu 15.10, LO 4.4.7, OO 4.1.3
Free Project: LibreOffice Songbook Architect (LOSA)
http://struckkai.blogspot.de/2015/04/li ... itect.html
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: [Solved] Save a draw shape as DIB bitmap?

Post by _savage »

The above works only for ODT files, correct? The Pictures folder does not exist in e.g. DOCX files and it’s not a virtual folder either…
musikai wrote:[…] tried to translate it into BASIC but am stuck at

Code: Select all

props[0].Value = "{}/Pictures/{}".format(cid, picture)
That’s a string formatting, you could also use simple concatenation:

Code: Select all

props[0].Value = cid + "/Pictures/" + picture
assuming that both cid and picture are strings, or coerce to strings.
musikai wrote:and expect also problems with

Code: Select all

thatgraphic.DIB[:5000] == thisgraphic.DIB[:5000]:
That compares the first 5000 bytes of both arrays, looks like a short-circuit equality check to me. Try comparing both complete DIB arrays.
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
Zizi64
Volunteer
Posts: 11362
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: [Solved] Save a draw shape as DIB bitmap?

Post by Zizi64 »

The above works only for ODT files, correct? The Pictures folder does not exist in e.g. DOCX files and it’s not a virtual folder either…
Do not use foreign file formats, when you use the AOO/LO API macros.
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
musikai
Volunteer
Posts: 294
Joined: Wed Nov 11, 2015 12:19 am

Re: [Solved] Save a draw shape as DIB bitmap?

Post by musikai »

_savage wrote:
musikai wrote:[…] tried to translate it into BASIC but am stuck at

Code: Select all

props[0].Value = "{}/Pictures/{}".format(cid, picture)
That’s a string formatting, you could also use simple concatenation:

Code: Select all

props[0].Value = cid + "/Pictures/" + picture
assuming that both cid and picture are strings, or coerce to strings.
Thank you!! This seems to work:

Code: Select all

props(0).Value = cid + "/Pictures/" + picture
_savage wrote:
musikai wrote:and expect also problems with

Code: Select all

thatgraphic.DIB[:5000] == thisgraphic.DIB[:5000]:
That compares the first 5000 bytes of both arrays, looks like a short-circuit equality check to me. Try comparing both complete DIB arrays.
Thank you! Above in teh full code there is a comparison of full DIB. (Don't know why also for only 5000 bytes later) Trying to find out how to compare these byte arrays in BASIC. Searching sthg like comparebytes() etc.

(starting to understand the advantages of python :D )
Win7 Pro, Lubuntu 15.10, LO 4.4.7, OO 4.1.3
Free Project: LibreOffice Songbook Architect (LOSA)
http://struckkai.blogspot.de/2015/04/li ... itect.html
hubert lambert
Posts: 145
Joined: Mon Jun 13, 2016 10:50 am

Re: [Solved] Save a draw shape as DIB bitmap?

Post by hubert lambert »

musikai wrote:

Code: Select all

thatgraphic.DIB[:5000] == thisgraphic.DIB[:5000]
That compares the first 5000 bytes of both arrays, looks like a short-circuit equality check to me. Try comparing both complete DIB arrays.
This is because, in some case and I don't really know why, DIB byte sequence can be slightly differents for svg files. So, by the way, you may expect that the comparison will fail for particular svg images...
musikai wrote:Above in the full code there is a comparison of full DIB. (Don't know why also for only 5000 bytes later) Trying to find out how to compare these byte arrays in BASIC. Searching sthg like comparebytes() etc.
I'm afraid this is not possible, as even the simplest array(1,2) = array(1,2) fails in basic!

But are you sure you really need to retrieve the internal file when you can use the GraphicExportFilter service, as you pointed it yourself?
AOOo 4.1.2 on Win7 | LibreOffice on various Linux systems
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: [Solved] Save a draw shape as DIB bitmap?

Post by _savage »

musikai wrote:Thank you! Above in teh full code there is a comparison of full DIB. (Don't know why also for only 5000 bytes later) Trying to find out how to compare these byte arrays in BASIC. Searching sthg like comparebytes() etc.
I think the 5000 is just a random assumption: if the first 5000 bytes are the same then the two pictures are most likely the same; I guess that assumption was made for performance reasons. Looking at the BASIC Guide you can determine the bounds of both arrays using LBound() and UBound() (link) and then use these two values in a for-loop (link) (make sure that both bounds for both pictures are the same) to compare the two pictures for equality.
musikai wrote:(starting to understand the advantages of python :D )
Python is a great and thorough and very production programming language indeed.
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
musikai
Volunteer
Posts: 294
Joined: Wed Nov 11, 2015 12:19 am

Re: [Solved] Save a draw shape as DIB bitmap?

Post by musikai »

Thank you both for your informations and ideas!!!!
hubert lambert wrote: But are you sure you really need to retrieve the internal file when you can use the GraphicExportFilter service, as you pointed it yourself?
Yes, that could be an option. But I would prefer to extract the original files and not create and test exportfilters for every possible filetype, eg. svg, pdf etc. and try to get the same dimensions, dpi etc. (and PDF (application/pdf) doesn't seem to work and created pdf-files of 0bytes)

_savage wrote:...determine the bounds of both arrays using LBound() and UBound()
Thank you. Tested the idea but both values are too similar on different objects.
Also comparing the contents or only parts of the arrays is of no luck because this is sooooo slow.

So best would be to use the original python file. Don't know if and how to get this into a BASIC extension. Or rewrite the whole extension in python :ugeek:
Perhaps I will look at the first idea from time to time. Not going to spend too much effort on this.

The best best best of course would be to get a better API again.
Win7 Pro, Lubuntu 15.10, LO 4.4.7, OO 4.1.3
Free Project: LibreOffice Songbook Architect (LOSA)
http://struckkai.blogspot.de/2015/04/li ... itect.html
Post Reply