Yksittäisen.pdf tiedostoon upotetun rasterikuvan tai aidon vektorigrafiikan uuttaminen LibreOffice [Star]Basic ympäristössä takaisin tiedostoksi.
REM ***** BASIC *****
Private baseUrl As String
Sub StartProcessing
Select Case OSName
Case "WIN"
baseUrl = Environ("userprofile") & "\Desktop\"
Case "LINUX", "MACOSX"
baseUrl = Environ("HOME") & "/Desktop/"
End Select
Dim oDoc As Object : oDoc = thisComponent
Dim filepicker As Object, localFile As String, sFileArray As Variant
filepicker = createUnoService("com.sun.star.ui.dialogs.FilePicker")
filepicker.setDisplayDirectory(Left(thisComponent.URL, InStrReverse(thisComponent.URL, "/") - 1))
filepicker.appendFilter("Portable Document Format", "*.pdf")
filepicker.setMultiSelectionMode(False)
If filepicker.Execute() Then
sFileArray = filepicker.getFiles()
localFile = sFileArray(0)
End If
filepicker = Nothing
If localFile = "" Then
MsgBox "Operation aborted by user", "48", "Open" : Exit Sub
End If
Dim sfa As Object, sResult As String
Dim inpStream As Object, inBytes() As Byte
sfa = CreateUnoService("com.sun.star.ucb.SimpleFileAccess")
inpStream = CreateUnoService("com.sun.star.io.DataInputStream")
inpStream = sfa.OpenFileRead(localFile)
inpStream.readSomeBytes(inBytes, 1000)
inpStream.CloseInput()
inpStream = Nothing
sResult = DumpBytes(inBytes)
Erase inBytes
Dim ext_mtype() As String
ext_mtype = Split(DetectImageType(sResult), "|")
sResult = ""
If ext_mtype(1) = "" Then
MsgBox "No supported image found", "48", "System"
Exit Sub
End If
Dim args(0) As New com.sun.star.beans.PropertyValue
args(0).Name = "Hidden"
args(0).Value =True
Dim pdfDoc As Object
pdfDoc = StarDesktop.loadComponentFromURL(localFile, "_blank", 0, args())
Dim oPages As Object, oPage As Object, oShape As Object
oPages = pdfDoc.getDrawPages()
If oPages.getCount() - 1 > 0 Then
MsgBox "Cannot handle multipage .pdf data", "48", "Sytem"
oPages = Nothing : pdfDoc.setModified(False)
args = Nothing : pdfDoc.dispose() : Exit Sub
End If
Dim j As Integer, oGraphic As Object, fColor As String, svg As String, boxW, boxH
oPage = oPages.getByIndex(0)
oShape = oPage.getByIndex(0)
For i = 0 To oPage.getCount() - 1
oShape = oPage.getByIndex(i)
If oShape.supportsService("com.sun.star.drawing.GraphicObjectShape") Then
oGraphic = oShape.Graphic : Exit For
ElseIf oShape.supportsService("com.sun.star.drawing.ClosedBezierShape") Then
svg = svg & ClosedBezierShapeToSvgPath(oShape)
End If
Next i
If svg <> "" Then
ssvg = "<svg xmlns=""http://www.w3.org/2000/svg"" version=""1.1"">" & Chr(13) & Chr(10) & svg & Chr(13) & Chr(10) & "</svg>"
Dim aBytes() As Byte
ReDim aBytes(Len(svg) -1)
For i = 1 To Len(svg)
aBytes(i - 1) = Asc(Mid(svg, i, 1))
Next
Dim oInstream As Object
oInstream = com.sun.star.io.SequenceInputStream.createStreamFromSequence(aBytes)
Erase aBytes
Dim oProvider As Object
Dim props(0) As New com.sun.star.beans.PropertyValue
oProvider=createUnoService("com.sun.star.graphic.GraphicProvider")
props(0).Name="InputStream" : props(0).Value = oInstream
oGraphic = oProvider.queryGraphic(props)
oInstream.CloseInput()
oInstream = Nothing
oProvider = Nothing
End If
pdfDoc.setModified(False)
pdfDoc.dispose()
oDoc.setModified(False)
If Not IsNull(oGraphic) And Not IsEmpty(oGraphic) Then
CopyToFile oGraphic, ext_mtype
oGraphic = Nothing
Else
MsgBox "No supported graphic found", "48", "System"
Exit Sub
End If
End Sub
Function DumpBytes(inBytes As Variant) As String
Dim aBytes(Ubound(inBytes)) As Byte
aBytes = inBytes
Dim i As Long, val As Long, sResult As String
For i = Lbound(aBytes) To Ubound(aBytes)
val = (aBytes(i) And &HFF)
sResult = sResult & Chr(val)
Next i
Erase aBytes : DumpBytes = sResult : sResult = ""
End Function
Function DetectImageType(sResult As String) As String
If InStr(sResult, "ÿØÿà") > 0 Or InStr(sResult, "ÿØÿÛ") > 0 Then
DetectImageType = ".jpg|image/jpeg"
ElseIf InStr(sResult, "GIF8") > 0 Or InStr(sResult, "<0000") > 0 Then
DetectImageType = ".gif|image/gif"
ElseIf InStr(sResult, "BM") > 0 Then
DetectImageType = ".bmp|image/bmp"
ElseIf InStr(sResult, "II*") > 0 Or InStr(sResult, "MM") > 0 Or InStr(sResult, "]ݱ") > 0 Then
DetectImageType = ".tiff|image/tiff"
ElseIf InStr(sResult, "RIFF") > 0 Then
DetectImageType = ".webp|image/webp"
ElseIf InStr(sResult, "<svg") > 0 Or InStr(sResult, "W1") OR Instr(sResult, "$M") > 0 Or Instr(sResult, "M¯") > 0 Or Instr(sResult, "½K") > 0Then
DetectImageType = ".svg|image/svg+xml"
Else
DetectImageType = ".png|image/png"
End If
End Function
Function ClosedBezierShapeToSvgPath(oShape As Variant) As String
Dim oPolyBez, aCoords, aFlags
Dim polyIdx As Long, ptIdx As Long
Dim pts, flg
Dim d As String
Dim x As Double, y As Double
Dim fillCol As String, strokeCol As String
Dim hasFill As Boolean, hasStroke As Boolean
oPolyBez = oShape.PolyPolygonBezier
aCoords = oPolyBez.Coordinates
aFlags = oPolyBez.Flags
d = ""
For polyIdx = LBound(aCoords) To UBound(aCoords)
pts = aCoords(polyIdx)
flg = aFlags(polyIdx)
If UBound(pts) < 0 Then GoTo NextPoly
x = pts(0).X
y = pts(0).Y
d = d & "M " & UnoToSvg(x) & " " & UnoToSvg(y) & " "
ptIdx = 1
Do While ptIdx <= UBound(pts)
Select Case flg(ptIdx)
Case 0
x = pts(ptIdx).X
y = pts(ptIdx).Y
d = d & "L " & UnoToSvg(x) & " " & UnoToSvg(y) & " "
ptIdx = ptIdx + 1
Case Else
If ptIdx + 2 <= UBound(pts) Then
Dim x1 As Double, y1 As Double
Dim x2 As Double, y2 As Double
Dim x3 As Double, y3 As Double
x1 = pts(ptIdx).X
y1 = pts(ptIdx).Y
x2 = pts(ptIdx + 1).X
y2 = pts(ptIdx + 1).Y
x3 = pts(ptIdx + 2).X
y3 = pts(ptIdx + 2).Y
d = d & "C " & UnoToSvg(x1) & " " & UnoToSvg(y1) & " " & _
UnoToSvg(x2) & " " & UnoToSvg(y2) & " " & _
UnoToSvg(x3) & " " & UnoToSvg(y3) & " "
ptIdx = ptIdx + 3
Else
x = pts(ptIdx).X
y = pts(ptIdx).Y
d = d & "L " & UnoToSvg(x) & " " & UnoToSvg(y) & " "
ptIdx = ptIdx + 1
End If
End Select
Loop
d = d & "Z "
NextPoly:
Next polyIdx
hasFill = (oShape.FillStyle <> com.sun.star.drawing.FillStyle.NONE)
hasStroke = (oShape.LineStyle <> com.sun.star.drawing.LineStyle.NONE)
If hasFill Then
fillCol = ColorToHex(oShape.FillColor)
Else
fillCol = "none"
End If
If hasStroke Then
strokeCol = ColorToHex(oShape.LineColor)
Else
strokeCol = "none"
End If
ClosedBezierShapeToSvgPath = "<path d=""" & Trim(d) & """ fill=""" & fillCol & _
""" stroke=""" & strokeCol & """ />"
End Function
Private Function UnoToSvg(ByVal n As Double) As String
Dim factor As Double
factor = 0.03779527559 ' 1/ (100 / 25.4 * 96)
UnoToSvg = Replace(CStr(n * factor), ",", ".")
End Function
Function ColorToHex(ByVal col As Long) As String
Dim r As Long, g As Long, b As Long
r = (col And &HFF0000) \ &H10000
g = (col And &H00FF00) \ &H100
b = (col And &H0000FF)
ColorToHex = "#" & Right("0" & Hex(r), 2) & _
Right("0" & Hex(g), 2) & _
Right("0" & Hex(b), 2)
End Function
Sub CopyToFile(oGraphic As Object, ext_mtype() As String)
destUrl = ConvertToUrl(baseUrl & "test" & UCase(Replace(ext_mtype(0), ".", "")) & ext_mtype(0))
Dim gPovider As Object
gPovider = CreateUnoService("com.sun.star.graphic.GraphicProvider")
Dim props(1) As New com.sun.star.beans.PropertyValue
Props(0).Name = "URL"
Props(0).Value = destUrl
Props(1).Name = "MimeType"
Props(1).Value = ext_mtype(1)
gPovider.storeGraphic(oGraphic, props)
props = Nothing : gPovider = Nothing : oGraphic = Nothing
Dim oShellExec As Object
oShellExec = CreateUnoService("com.sun.star.system.SystemShellExecute")
oShellExec.execute(destUrl, "", 0)
oShellExec = Nothing
End Sub
Function InStrReverse(sText As String, search As String) As Long
If sText = "" Or search = "" Or Len(search) > Len(sText) Then
InStrReverse = 0
Exit Function
End If
Dim i As Long
For i = Len(sText) To 1 Step -1
If Mid(sText, i, Len(search)) = search Then
InStrReverse = i : Exit Function
End If
Next i
End Function
Function OSName As String
With GlobalScope.Basiclibraries
If Not .IsLibraryLoaded("Tools") Then .LoadLibrary("Tools")
End With
Dim keyNode As Object
keyNode = Tools.Misc.GetRegistryKeyContent("org.openoffice.Office.Common/Help")
OSName = keyNode.GetByName("System")
End Function
Sub OnClose
thisComponent.setModified(False)
End SubHalutessaan valmiin testiprojektin siihen liittyvine .pdf testitiedostoineen voi imaista täältä
HV (hyvää vappua jo etukäteen)