[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

[Solved] Save a draw shape as DIB bitmap?

Post by _savage »

Hello,

Given a Writer document that contains a draw shape, is it possible to get a DIB bitmap graphics for that shape and save it?

Thanks :)
Last edited by _savage on Mon Jul 30, 2018 8:57 pm, edited 1 time in total.
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Save a draw shape as DIB bitmap?

Post by Zizi64 »

My opinion: use the PNG filetype instead ow the Windows related DIB fileformat. The AOO and LO are platform indepentent aplications.


"The 'Portable Network Graphics' is a raster graphics file format that supports lossless data compression. PNG was created as an improved, non-patented replacement for Graphics Interchange Format (GIF), and is the most used lossless image compression format on the Internet."
https://en.wikipedia.org/wiki/Portable_Network_Graphics


"DIB is a graphics file format used by Windows. DIB stands for “Device-Independent Bitmap.” DIB files are bitmapped graphics that represent color formats. Similar to .BMP format, except they have a different header."
http://whatis.techtarget.com/fileformat ... ent-bitmap


The AOO and LO have .PNG and .BMP export filters, and you can control those filters by a macro code.
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.
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Save a draw shape as DIB bitmap?

Post by _savage »

Zizi64 wrote:The AOO and LO have .PNG and .BMP export filters, and you can control those filters by a macro code.
That macro code you mention is what I am looking for! What I have managed so far is reading the DIB bitmap for an image:

Code: Select all

shape_enum = document.DrawPage.createEnumeration()
while shape_enum.hasMoreElements():
    shape = shape_enum.nextElement()
    if hasattr(shape, "Graphic"):
        graphic = getattr(shape, "Graphic")
        bmp = graphic.DIB.value # Get the DIB bitmap for the graphic.
    else:
        # How to get a DIB (or PNG) for this draw shape? If that is at all possible.
How would I go about the else case here?

Bonus: you mention that it is possible to access the PNG instead of the DIB bitmap graphic for the if case? At the moment I convert to PNG later which works fine as well.
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Save a draw shape as DIB bitmap?

Post by Zizi64 »

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.
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Save a draw shape as DIB bitmap?

Post by _savage »

Thank you for the second link. I tried it, and none of the shapes in my documents supports the OLE2Shape service which is probably because these are not charts in the first place. However, my Python segfaults when I try to set the source document:

Code: Select all

>>> sm = uno.getComponentContext().ServiceManager
>>> s = sm.createInstanceWithContext("com.sun.star.drawing.GraphicExportFilter", uno.getComponentContext())
>>> s.setSourceDocument(shape)

Thread 1 "python" received signal SIGSEGV, Segmentation fault.
0x00007ffff09a940d in Application::GetSolarMutex() () from /usr/lib64/libreoffice/program/../program/libmergedlo.so
This is on Linux, but happens just the same on Mac. The shape argument is one of the shapes I iterate over from the document's DrawPage, see the code above. Not sure I have the time right now to debug the segfault :cry:
Last edited by _savage on Mon Apr 18, 2016 7:19 am, edited 3 times in total.
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: Save a draw shape as DIB bitmap?

Post by musikai »

For Draw there is an extension that is able to export shapes as raster images.

The extension for OO seems to be outdated. I only used the LO version exportasimages-0-9-3.oxt in LibreOffice from here:
http://extensions.libreoffice.org/exten ... -as-images

This might be useful to look at the code how GraphicExportFilter is used in Draw. If and how this can used in Writer is unkown to me.
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: Save a draw shape as DIB bitmap?

Post by _savage »

musikai wrote:For Draw there is an extension that is able to export shapes as raster images.

The extension for OO seems to be outdated. I only used the LO version exportasimages-0-9-3.oxt in LibreOffice from here:
http://extensions.libreoffice.org/exten ... -as-images

This might be useful to look at the code how GraphicExportFilter is used in Draw. If and how this can used in Writer is unkown to me.
Thank you! The ExportShape subroutine in that extension noodles around a lot to set up the property values for the final call sequence. That final call is the same as what I've tried above when setSourceDocument crashed in Python.:

Code: Select all

xExporter = createUnoService( "com.sun.star.drawing.GraphicExportFilter" )
xExporter.setSourceDocument( oShape )
xExporter.filter( aArgs() )
Last edited by _savage on Mon Apr 18, 2016 7:22 am, edited 1 time in total.
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Save a draw shape as DIB bitmap?

Post by Zizi64 »

This short Basic code works for me in my LO4.4.7 and AOO 4.1.2. when I really select a Shape (there is not error handling in my code):

Code: Select all

Sub  

  oCurSelection = thisComponent.getCurrentSelection()
 
  Dim args(1) as new com.sun.star.beans.PropertyValue
  args(0).Name = "URL"
  args(0).Value = "file:///E:/test.png"
  args(1).Name = "MimeType"
  args(1).Value = "image/png"
 
  gef = CreateUnoService("com.sun.star.drawing.GraphicExportFilter")
  gef.setSourceDocument(oCurSelection)
  gef.filter(args)
End Sub
Modify the value of the URL in the code (embedded into the attached document), and then try the document. Select a shape, and then click on the custom toolbar label named StoreSelectionAsImage
Export selection as picture.odt
(12.55 KiB) Downloaded 376 times
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.
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Save a draw shape as DIB bitmap?

Post by _savage »

Your example document runs into the same segfault when I use Python (see above), and I suspect that there is a problem with the Python-UNO bridge and I have filed a bug.

Have you tried this in Python? (LibreOffice 5.0.5.2 55b006a02d247b5f7215fc6ea0fde844b30035b3)
Last edited by _savage on Mon Apr 18, 2016 7:48 am, edited 1 time in total.
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Save a draw shape as DIB bitmap?

Post by Zizi64 »

Have you tried this in Python? (LibreOffice 5.0.5.2
Sorry, I never used the Python language and I do not know how to use the Python scripts and code snippets...
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.
B Marcelly
Volunteer
Posts: 1160
Joined: Mon Oct 08, 2007 1:26 am
Location: France, Paris area

Re: Save a draw shape as DIB bitmap?

Post by B Marcelly »

Hi,
_savage wants to export a graphic object from a Writer document.
Zizi64 code works because it contains shapes, but not a graphic object.
If the Writer document contains an image ( = graphic object), the code throws : IllegalArgument Exception.
[url=https://www.openoffice.org/api/docs/common/ref/com/sun/star/document/XExporter.html#setSourceDocument]API documentation[/url] of setSourceDocument wrote:Throws
com::sun::star::lang::IllegalArgumentException if Document does not support any service which is supported by this exporter
Use Xray to display the supported services of an image.
An image in a Draw or Calc document supports service com.sun.star.drawing.GraphicObjectShape.
An image in a Writer document supports service com.sun.star.text.TextGraphicObject.

I can't see a solution to this incompatibility of Writer.
Bernard

OpenOffice.org 1.1.5 / Apache OpenOffice 4.1.1 / LibreOffice 5.0.5
MS-Windows 7 Home SP1
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Save a draw shape as DIB bitmap?

Post by Zizi64 »

_savage wants to export a graphic object from a Writer document.
He wrote 'shape'...
Given a Writer document that contains a draw shape, is it possible to get a DIB bitmap graphics for that shape and save it?
Sorry, I misunderstood the task...
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: Save a draw shape as DIB bitmap?

Post by musikai »

You understood correctly, he wants to export a shape, not a textgraphic object.

Savage, have you tried if your code works in lo 4.4.7 or in oo4.1.2? In your bug report i saw that you used lo5.0.5 and i have some macros that throw errors in lo5 versions because of its bugs. They work correctly in oo4.12 and lo4.4.7
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: Save a draw shape as DIB bitmap?

Post by _savage »

B Marcelly wrote:_savage wants to export a graphic object from a Writer document.
I am iterating over com.sun.star.drawing.XShape pyuno objects, see my code above. Hopefully referring to those objects as "shapes" was not misleading?
Zizi64 wrote:He wrote 'shape'... Sorry, I misunderstood the task...
I think you understood correctly, Tibor.
musikai wrote:_savage, have you tried if your code works in lo 4.4.7 or in oo4.1.2? In your bug report i saw that you used lo5.0.5 and i have some macros that throw errors in lo5 versions because of its bugs. They work correctly in oo4.12 and lo4.4.7
Tried the latest LO 5.1.2 and the older LO 4.4.7.2, and both segfault. I then tried to use AOO 4.1.2 but it doesn't come with a python interpreter on Mac; the Python-UNO bridge seems to be built for Python2, but does not work on my Mac:

Code: Select all

>>> import uno
Fatal Python error: PyThreadState_Get: no current thread
Abort trap: 6
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Save a draw shape as DIB bitmap?

Post by _savage »

I would like to pick up this thread again. While iterating over a Writer document (see also this question), I come across TextPortionType that are “Frame” and then iterate over their content. If such a frame’s content object supports the “com.sun.star.drawing.Shape” service, then getShapeType() gives me an object of one of these shape types.

Now I would like to save that shape as a bitmap image.

This probably can’t be done directly (can it?) so I thought to copy the shape object to the clipboard, and paste it into a new instance of Draw; from there, export the content as an image (ideally back to the clipboard so I can fetch its bytes content).

I keep looking for documentation on using the clipboard (XDispatchHelper and uno:Copy and uno:Paste?) but can’t find much useful information.

Does anybody have useful references and tips on how to go about this?
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
UnklDonald418
Volunteer
Posts: 1546
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Save a draw shape as DIB bitmap?

Post by UnklDonald418 »

Have you looked at 5.23 Manipulating the clipboard in Andrew Pitonyak's "Useful Macro Information document"?
http://www.pitonyak.org/oo.php
Look in Downloads list for PDF English Macro Document
You might also find something useful in 5.9. Loading/Inserting an image into your document
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Save a draw shape as DIB bitmap?

Post by _savage »

UnklDonald418 wrote:Have you looked at 5.23 Manipulating the clipboard in Andrew Pitonyak's "Useful Macro Information document"?
http://www.pitonyak.org/oo.php
Yup, and I’ve tried the following code:

Code: Select all

# Create the DispatchHelper service.
context = uno.getComponentContext()
dispatcher = context.ServiceManager.createInstanceWithContext("com.sun.star.frame.DispatchHelper", context) 

# shape_obj is a com.sun.star.drawing.Shape
controller = document.getCurrentController()
controller.select(shape_obj)                                                           
dispatcher.executeDispatch(controller, ".uno:Copy", "", 0, ())  
When I now go into Draw and Ctrl-V (to paste from the system clipboard) then nothing happens. Inspecting the clipboard shows that it’s empty.
UnklDonald418 wrote:You might also find something useful in 5.9. Loading/Inserting an image into your document
These are macros related to bitmap images, not draw shapes.
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
UnklDonald418
Volunteer
Posts: 1546
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Save a draw shape as DIB bitmap?

Post by UnklDonald418 »

_savage
Hopefully, this will help you with your problem.
I inserted a shape into a Writer document.
I selected the shape and began recording a macro.
I pressed <Ctrl>C, then stopped recording and the recorder saved the following macro.

Code: Select all

rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
Next I used <Ctrl>V to paste the shape onto a Draw slide. I tried resizing to verify it was a vector graphic. The interesting bit here is that the macro copied the Frame, not the Shape object.
Then I tried <Ctrl><Shift>V and selected Bitmap. When I expanded the pasted shape it was pixelated confirming that it was a bitmap image.
I returned to Writer and recorded a second macro that was simply <Ctrl><Shift>V and selected Bitmap.

Code: Select all

rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "SelectedFormat"
args1(0).Value = 2

dispatcher.executeDispatch(document, ".uno:ClipboardFormatItems", "", 0, args1())
Now when I select a shape and Run the first macro it copies the shape into the clipboard.
When I Run the second macro it pastes the contents of the clipboard as a bitmap image.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

Re: Save a draw shape as DIB bitmap?

Post by _savage »

Zizi64 wrote:This is a Calc example, but maybe you can use it.
http://www.ooowiki.de/DiagrammExport.html
With some slight modification, that worked. See also GraphicExportFilter for some documentation on filter parameters, but it seems that the documentation is incomplete for many media types.
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 you still just want to export selected draw shapes from writer to png or svg then you can play with this code.
It is a snippet of my extension "ChordDiagrams". I just changed the default to png instead of svg for here.

Notes: On Linux you have to have the draw component installed (on Linux you have the choice of only installing the writer component.)

Multiple selected draw shapes will be exported to single files and you will be asked for a name for each and a dpi for all.
If you want to export to svg you have to select .svg in the filetype of the save_as_Dialog.
(This code also corrects the corrupted default svg format of OpenOffice.)

Still both png's and svg's might have some pixels cut of from the edges. There's nothing I can do about it.

Sorry for the ugly code

Code: Select all

REM  *****  BASIC  *****

Sub Main
export_selected_objects_as_png_or_svg
End Sub

sub export_selected_objects_as_png_or_svg 
 on error goto ErrorHandler

Dim args(2) as new com.sun.star.beans.PropertyValue
Dim aFilterData (7) as new com.sun.star.beans.PropertyValue
DPIalreadychosen=0
for i=0 to ThisComponent.CurrentSelection.count-1
g = ThisComponent.CurrentSelection(i)
  if g.supportsService("com.sun.star.drawing.GraphicObjectShape") or g.supportsService("com.sun.star.drawing.RectangleShape") or g.supportsService("com.sun.star.drawing.CustomShape") or g.supportsService("com.sun.star.drawing.Shape") then

 oFilter=CreateUnoService("com.sun.star.drawing.GraphicExportFilter")

    if (g.supportsService("com.sun.star.drawing.Shape") and instr(g.name,"chord:")) or (g.supportsService("com.sun.star.drawing.Shape") and instr(g.name,"scale:")) then

 GraphicNamearray = split(g.name,":")
 GraphicName=mid(GraphicNamearray(1),2)
 GraphicName=replace(GraphicName,"/","-")
 	else
 	GraphicName="Name"
 	end if
saveurl = show_save_dialog(GraphicName)

if saveurl="" then exit for

if instr(saveurl,".svg")>0 then
saveMediatype = "image/svg+xml"
elseif instr(saveurl,".png")>0 and DPIalreadychosen=0 then
saveMediatype = "image/png"
setDPI = cint(inputbox("Set DPI","Set DPI","300"))
if setDPI=0 then exit sub
DPIalreadychosen=1
end if

rem----------prepare progressbar------------------------------------------       
oProgressBar = ThisComponent.CurrentController.getStatusIndicator()
rem--------------show progress------------------------------------------
oProgressBar.start( "Exporting Graphic", 3 )

oProgressBar.setValue(1)

if saveMediatype="image/svg+xml" and isOpenOffice=1 then
saveurl= replace(saveurl,".svg","_temp.svg")
end if

oProgressBar.setValue(2)




PixelWidth=cint(g.Size.Width/2540.0/TwipsPerPixelX()*1440/96*setDPI)
PixelHeight=cint(g.Size.Height/2540.0/TwipsPerPixelY()*1440/96*setDPI)

 		aFilterData(0).Name = "Width"
 		aFilterData(0).Value = cint(g.Size.Width/100)
		aFilterData(1).Name = "Height"
		aFilterData(1).Value = cint(g.Size.Height/100)
		aFilterData(2).Name = "Translucent"
		aFilterData(2).Value = true
 		aFilterData(3).Name = "PixelWidth"
 		aFilterData(3).Value = PixelWidth
		aFilterData(4).Name = "PixelHeight"
		aFilterData(4).Value = PixelHeight
 		aFilterData(5).Name = "LogicalWidth"
 		aFilterData(5).Value = cint(g.Size.Width)
		aFilterData(6).Name = "LogicalHeight"
		aFilterData(6).Value = cint(g.Size.Height)
		aFilterData(7).Name  = "Resolution"
	    aFilterData(7).Value = setDPI

		



 oFilter.setSourceDocument(g)
 args(0).Name = "URL"
 args(0).Value = saveurl
 args(1).Name = "MediaType"
 args(1).Value = saveMediatype
 args(2).Name = "FilterData"
 args(2).Value = aFilterData()


 oFilter.filter(args())
 
oProgressBar.setValue(3) 
oProgressBar.end
 
if saveMediatype = "image/svg+xml" and isOpenOffice=1 then repairopenofficesvg(saveurl)

else
msgbox "Please select a Graphic!"
end if
next
exit sub
ErrorHandler:
msgbox "Please select a Graphic!"
end sub

function show_save_dialog(defaultname)
	dim aurl as object
	dim s as string
	dim oDlg as object
	
	sFilePickerArgs = Array(_
	com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_AUTOEXTENSION )	
	oDlg = createUnoService("com.sun.star.ui.dialogs.FilePicker")
	oDlg.initialize(sFilePickerArgs())
	oDlg.setMultiSelectionMode(false)
	oDlg.appendFilter("png Files (.png)", "*.png" )
	oDlg.appendFilter("SVG Files (.svg)", "*.svg" )	

	oDlg.setTitle("Save As....")
	oDlg.setDefaultName(defaultname)
	if oDlg.execute() then
		aUrl = oDlg.getFiles()
		s = aUrl(0)
		if len(s) > 0 then
			rem MsgBox("File Selected: " & s & chr(13))
		end if
	else
		s = ""
	end if
	show_save_dialog = s
end function

sub repairopenofficesvg(fileURL)

oSFA = CreateUnoService("com.sun.star.ucb.SimpleFileAccess")
oTextinputStream = CreateUnoService("com.sun.star.io.TextInputStream")

inputfile = fileURL
oinputStream = oSFA.openFileRead(inputfile)
oTextinputStream.setInputStream(oinputStream)

outputfile = replace(fileURL,"_temp.svg",".svg")
if fileexists(outputfile) then kill(outputfile)
oTextoutputStream = CreateUnoService("com.sun.star.io.TextOutputStream")
ooutputStream = oSFA.openFileWrite(outputfile)
oTextoutputStream.setOutputStream(ooutputStream)

do while oTextinputStream.isEOF()=0
stringA = oTextinputStream.readLine()
 if instr(stringA,"<svg") and instr(stringA,"xml:space=""preserve"">") and instr(stringA,"xmlns=""http://www.w3.org/2000/svg""")=0  then stringA=replace(stringA,">"," xmlns=""http://www.w3.org/2000/svg"">")
oTextoutputStream.writeString(stringA & CHR$(10))
loop

oTextinputStream.closeInput()
oTextoutputStream.closeOutput()


if fileexists(inputfile) then kill(inputfile)

end sub

function isOpenOffice
Dim oConfigProvider as Object
Dim aNodePath(0) as new com.sun.star.beans.PropertyValue
	oConfigProvider = createUnoService("com.sun.star.configuration.ConfigurationProvider")
	aNodePath(0).Name = "nodepath"
	aNodePath(0).Value = "org.openoffice.Setup/Product"

		oProdNameAccess() = oConfigProvider.createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", aNodePath())


	sProdName = oProdNameAccess.getByName("ooName")
	isOpenOffice=0
rem	isOpenOffice=1  ' set for default OpenOffice compatibility mode
	
	if sProdName="OpenOffice" then isOpenOffice=1

end function
Attachments
export_selected_objects_as_png_or_svg.odt
(11.96 KiB) Downloaded 349 times
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: Save a draw shape as DIB bitmap?

Post by _savage »

Zizi64 wrote:The AOO and LO have .PNG and .BMP export filters, and you can control those filters by a macro code.
I am still somewhat unclear on this. Suppose somebody drops a GIF, a JPG, and a PNG image in a document, how do I get hold of these original image files? Using an export filter I can retrieve the image (or any shape object, for that matter) as a PNG… but can I access the original file that was inserted? There is some information available from the GraphicDescriptor, e.g. the MIME type or a bitmap (DIB), but I’m unable to track down the original image (if that’s at all available) :?
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
RoryOF
Moderator
Posts: 34611
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

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

Post by RoryOF »

You can access the internal copy of the picture by Saving the file in ODF format (,odt. .odg etc), opening it with an archive utility (it is a .zip file in disguise), then copying the image from the folder Pictures in that archive.
 Edit: I have just checked, a .png, a gif and a .jpg file are renamed internally, but are stored in their respective original formats. I have not examined if they are resampled. 
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

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

Post by _savage »

RoryOF wrote:You can access the internal copy of the picture by Saving the file in ODF format (,odt. .odg etc), opening it with an archive utility (it is a .zip file in disguise), then copying the image from the folder Pictures in that archive.
Thanks Rory! No way to access that through the DOM programmatically? I had hoped that a bytes array of the original image floats around somewhere…
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
RoryOF
Moderator
Posts: 34611
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

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

Post by RoryOF »

I can't say, but searching in the API might help; One can programatically extract anything from a .zip archive - python in particular is good for this.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

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

Post by Zizi64 »

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.
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

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

Post by _savage »

RoryOF wrote:I can't say, but searching in the API might help; One can programatically extract anything from a .zip archive - python in particular is good for this.
Rory, I’m familiar with Python’s zipfile module. Using that would still require finding that mapping between the image file in the zip and the internal DOM component. See below…
Zizi, thank you, that’s an interesting extension! I was able to install it, but can’t seem to find it in the menu or use it otherwise.

Looking at the extension’s code, file PicExtract/PicExtract.xba seems to contain the interesting goodness: depending on the supported services of an image/shape component it reads GraphicUrl or FillBitmapUrl, neither of which are defined for the images in my test document. Furthermore, it uses getDocumentStorage() to access the Pictures/ folder of that document storage service, but that, too, does not exist for my test document. So I wonder if that extension as a whole is still functional at all with the current Writer version…
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

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

Post by Zizi64 »

Zizi, thank you, that’s an interesting extension! I was able to install it, but can’t seem to find it in the menu or use it otherwise.
There is a new toolbar under the main menu (this is the default location after the installing the extension)
PicExtract.png
PicExtract.png (7.91 KiB) Viewed 9838 times
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.
_savage
Posts: 187
Joined: Sun Apr 21, 2013 12:55 am

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

Post by _savage »

Zizi64 wrote:There is a new toolbar under the main menu (this is the default location after the installing the extension)
You are correct, I didn’t see that :D However, running the extension throws an exception that confirms my suspicion above: the code might be outdated:

Code: Select all

An exception occurred 
Type: com.sun.star.uno.RuntimeException
Message: Getting from this property is not supported.
That’s reading the GraphicUrl property for a TextGraphicObject. I will poke around some more, and see what I can find…
Mac 10.14 using LO 7.2.0.2, Gentoo Linux using LO 7.2.3.2 headless.
User avatar
Zizi64
Volunteer
Posts: 11358
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

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

Post by Zizi64 »

However, running the extension throws an exception
The extensions are third party softwares. You must contact to the author of the extension, or (maybe) you can fix the problem based on the open source program code.
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 »

I'm the author and stacked together this code as non-educated amateur :-) .

The problem is that an API change in LO6+. In all OO and LO_upto5

Code: Select all

graphic.GraphicURL
showed the internal image name of an embedded graphic or the url of a linked graphic file.
In LO6+ a linked graphic url now can be found at

Code: Select all

graphic.Graphic.OriginURL
but I don't know how to find the internal graphic name of an embedded graphic. So the extension is incompatible with LO6+.

But the following code is compatible with all versions and can extract all embedded images to a subfolder "pictures":

Code: Select all

sub Extract_all_images
oDoc=thiscomponent
If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then GlobalScope.BasicLibraries.LoadLibrary("Tools")
if len(oDoc.getURL())=0 then
 msgbox "Save document first!"
 exit sub
end if
  workdirfull = DirectoryNameoutofPath(oDoc.getURL(),"/") & "/"
  docname = GetFileNameWithoutExtension(oDoc.getURL(),"/")
  imagepath = convertfromUrl(workdirfull & "Pictures" & getpathseparator)
  
oFic = oDoc.DocumentStorage.getByName("Pictures").getElementNames
	for i = 0 to ubound(oFic)
	sImageName = oFic(i)
	Extract_an_Image(imagepath,sImageName)
	next
end sub

function Extract_an_Image(imagepath,sImageName)
dim args(0)
	z = CreateUnoService("com.sun.star.packages.Package")
    args(0)= Thiscomponent.url
    z.initialize(args())
    oInputstream=z.getByHierarchicalName("Pictures/" & sImageName).GetInputStream
   
    oSimpleFileAccess = createUnoService("com.sun.star.ucb.SimpleFileAccess")

    oSimpleFileAccess.WriteFile(converttourl(imagepath & sImageName), oInputstream)
	
end function
-
-
-
But your original question was how to save a draw shape as bitmap. Here is a code that lets you save selected draw shapes as png or svg (but SVG may be broken on Linux OS, not my fault):

Code: Select all

sub export_selected_Draw_Shapes_as_png 'or as svg
 on error goto ErrorHandler

Dim args(2) as new com.sun.star.beans.PropertyValue
Dim aFilterData (7) as new com.sun.star.beans.PropertyValue
DPIalreadychosen=0
for i=0 to ThisComponent.CurrentSelection.count-1
g = ThisComponent.CurrentSelection(i)
  if g.supportsService("com.sun.star.drawing.GraphicObjectShape") or g.supportsService("com.sun.star.drawing.RectangleShape") or g.supportsService("com.sun.star.drawing.CustomShape") or g.supportsService("com.sun.star.drawing.Shape") then

 oFilter=CreateUnoService("com.sun.star.drawing.GraphicExportFilter")


GraphicName = g.name
if len(GraphicName)>0 then 
GraphicName=replace(GraphicName,"/","_")
GraphicName=replace(GraphicName,":","_")
else
GraphicName="Name"
end if

 
saveurl = show_save_dialog2(GraphicName)

if saveurl="" then exit for

if instr(saveurl,".svg")>0 then
saveMediatype = "image/svg+xml"
elseif instr(saveurl,".png")>0 and DPIalreadychosen=0 then
saveMediatype = "image/png"
setDPI = cint(inputbox("Set DPI","Set DPI","300"))
if setDPI=0 then exit sub
DPIalreadychosen=1
end if

rem----------prepare progressbar------------------------------------------       
oProgressBar = ThisComponent.CurrentController.getStatusIndicator()
rem--------------show progress------------------------------------------
oProgressBar.start( "Exporting Graphic", 3 )

oProgressBar.setValue(1)

if saveMediatype="image/svg+xml" and isOpenOffice=1 then
saveurl= replace(saveurl,".svg","_temp.svg")
end if

oProgressBar.setValue(2)

exWidth=g.BoundRect.Width
exHeight=g.BoundRect.Height


PixelWidth=cint(exWidth/2540.0/TwipsPerPixelX()*1440/96*setDPI)
PixelHeight=cint(exHeight/2540.0/TwipsPerPixelY()*1440/96*setDPI)

 		aFilterData(0).Name = "Width"
 		aFilterData(0).Value = cint(exWidth/100)
		aFilterData(1).Name = "Height"
		aFilterData(1).Value = cint(exHeight/100)
		aFilterData(2).Name = "Translucent"
		aFilterData(2).Value = true
 		aFilterData(3).Name = "PixelWidth"
 		aFilterData(3).Value = PixelWidth
		aFilterData(4).Name = "PixelHeight"
		aFilterData(4).Value = PixelHeight
 		aFilterData(5).Name = "LogicalWidth"
 		aFilterData(5).Value = cint(exWidth)
		aFilterData(6).Name = "LogicalHeight"
		aFilterData(6).Value = cint(exHeight)
		aFilterData(7).Name  = "Resolution"
	    aFilterData(7).Value = setDPI

		



 oFilter.setSourceDocument(g)
 args(0).Name = "URL"
 args(0).Value = saveurl
 args(1).Name = "MediaType"
 args(1).Value = saveMediatype
 args(2).Name = "FilterData"
 args(2).Value = aFilterData()


 oFilter.filter(args())
 
oProgressBar.setValue(3) 
oProgressBar.end
 
if saveMediatype = "image/svg+xml" and is_OpenOffice=1 then repairopenofficesvg2(saveurl)

else
msgbox "Please select a Graphic!"
end if
next
exit sub
ErrorHandler:
msgbox "Please select a Graphic!"
end sub

function show_save_dialog2(defaultname)
	dim aurl as object
	dim s as string
	dim oDlg as object
	
	sFilePickerArgs = Array(_
	com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_AUTOEXTENSION )	
	oDlg = createUnoService("com.sun.star.ui.dialogs.FilePicker")
	oDlg.initialize(sFilePickerArgs())
	oDlg.setMultiSelectionMode(false)
	oDlg.appendFilter("png Files (.png)", "*.png" )
	oDlg.appendFilter("SVG Files (.svg)", "*.svg" )	
rem	oDlg.appendFilter("png Files (.png)", "*.png" )
	oDlg.setTitle("Save As....")
	oDlg.setDefaultName(defaultname)
	if oDlg.execute() then
		aUrl = oDlg.getFiles()
		s = aUrl(0)
		if len(s) > 0 then
			rem MsgBox("File Selected: " & s & chr(13))
		end if
	else
		s = ""
	end if
	show_save_dialog2 = s
end function

sub repairopenofficesvg2(fileURL)

oSFA = CreateUnoService("com.sun.star.ucb.SimpleFileAccess")
oTextinputStream = CreateUnoService("com.sun.star.io.TextInputStream")

inputfile = fileURL
oinputStream = oSFA.openFileRead(inputfile)
oTextinputStream.setInputStream(oinputStream)

outputfile = replace(fileURL,"_temp.svg",".svg")
if fileexists(outputfile) then kill(outputfile)
oTextoutputStream = CreateUnoService("com.sun.star.io.TextOutputStream")
ooutputStream = oSFA.openFileWrite(outputfile)
oTextoutputStream.setOutputStream(ooutputStream)

do while oTextinputStream.isEOF()=0
stringA = oTextinputStream.readLine()
 if instr(stringA,"<svg") and instr(stringA,"xml:space=""preserve"">") and instr(stringA,"xmlns=""http://www.w3.org/2000/svg""")=0  then stringA=replace(stringA,">"," xmlns=""http://www.w3.org/2000/svg"">")
oTextoutputStream.writeString(stringA & CHR$(10))
loop

oTextinputStream.closeInput()
oTextoutputStream.closeOutput()


if fileexists(inputfile) then kill(inputfile)

end sub

function is_OpenOffice
Dim oConfigProvider as Object
Dim aNodePath(0) as new com.sun.star.beans.PropertyValue
	oConfigProvider = createUnoService("com.sun.star.configuration.ConfigurationProvider")
	aNodePath(0).Name = "nodepath"
	aNodePath(0).Value = "org.openoffice.Setup/Product"

		oProdNameAccess() = oConfigProvider.createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", aNodePath())


	sProdName = oProdNameAccess.getByName("ooName")
	is_OpenOffice=0
rem	is_OpenOffice=1  ' set for default OpenOffice compatibility mode
	
	if sProdName="OpenOffice" then is_OpenOffice=1

end function
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