Jump to content

Svg2Png


wakillon
 Share

Recommended Posts

Convert SVG file to PNG using Cairo and rsvg libraries (and their imports)

#Region    ;************ Includes ************
#include <File.au3>
#EndRegion ;************ Includes ************

; typedef enum _cairo_status
Global Const $CAIRO_STATUS_SUCCESS = 0
Global Const $CAIRO_STATUS_NO_MEMORY = 1
Global Const $CAIRO_STATUS_INVALID_RESTORE = 2
Global Const $CAIRO_STATUS_INVALID_POP_GROUP = 3
Global Const $CAIRO_STATUS_NO_CURRENT_POINT = 4
Global Const $CAIRO_STATUS_INVALID_MATRIX = 5
Global Const $CAIRO_STATUS_INVALID_STATUS = 6
Global Const $CAIRO_STATUS_NULL_POINTER = 7
Global Const $CAIRO_STATUS_INVALID_STRING = 8
Global Const $CAIRO_STATUS_INVALID_PATH_DATA = 9
Global Const $CAIRO_STATUS_READ_ERROR = 10
Global Const $CAIRO_STATUS_WRITE_ERROR = 11
Global Const $CAIRO_STATUS_SURFACE_FINISHED = 12
Global Const $CAIRO_STATUS_SURFACE_TYPE_MISMATCH = 13
Global Const $CAIRO_STATUS_PATTERN_TYPE_MISMATCH = 14
Global Const $CAIRO_STATUS_INVALID_CONTENT = 15
Global Const $CAIRO_STATUS_INVALID_FORMAT = 16
Global Const $CAIRO_STATUS_INVALID_VISUAL = 17
Global Const $CAIRO_STATUS_FILE_NOT_FOUND = 18
Global Const $CAIRO_STATUS_INVALID_DASH = 19
Global Const $CAIRO_STATUS_INVALID_DSC_COMMENT = 20
Global Const $CAIRO_STATUS_INVALID_INDEX = 21
Global Const $CAIRO_STATUS_CLIP_NOT_REPRESENTABLE = 22
Global Const $CAIRO_STATUS_TEMP_FILE_ERROR = 23
Global Const $CAIRO_STATUS_INVALID_STRIDE = 24
Global Const $CAIRO_STATUS_FONT_TYPE_MISMATCH = 25
Global Const $CAIRO_STATUS_USER_FONT_IMMUTABLE = 26
Global Const $CAIRO_STATUS_USER_FONT_ERROR = 27
Global Const $CAIRO_STATUS_NEGATIVE_COUNT = 28
Global Const $CAIRO_STATUS_INVALID_CLUSTERS = 29
Global Const $CAIRO_STATUS_INVALID_SLANT = 30
Global Const $CAIRO_STATUS_INVALID_WEIGHT = 31
Global Const $CAIRO_STATUS_INVALID_SIZE = 32
Global Const $CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED = 33
Global Const $CAIRO_STATUS_DEVICE_TYPE_MISMATCH = 34
Global Const $CAIRO_STATUS_DEVICE_ERROR = 35
Global Const $CAIRO_STATUS_INVALID_MESH_CONSTRUCTION = 36
Global Const $CAIRO_STATUS_DEVICE_FINISHED = 37
Global Const $CAIRO_STATUS_LAST_STATUS = 38

; typedef enum _cairo_format
Global Const $CAIRO_FORMAT_INVALID   = -1
Global Const $CAIRO_FORMAT_ARGB32    = 0
Global Const $CAIRO_FORMAT_RGB24     = 1
Global Const $CAIRO_FORMAT_A8        = 2
Global Const $CAIRO_FORMAT_A1        = 3
Global Const $CAIRO_FORMAT_RGB16_565 = 4
Global Const $CAIRO_FORMAT_RGB30     = 5

; Check libraries.
$aList = _FileListToArray ( @ScriptDir, '*.dll', 1, 0 )
For $i = 1 To UBound ( $aList ) -1
    If _GetBinaryType ( @ScriptDir & '\' & $aList[$i] ) <> 'i386' Then Exit MsgBox ( 262144+16, 'Error', $aList[$i] & ' is not 32bit !', 5 )
;~  ConsoleWrite ( $aList[$i] & @TAB & 'Version ' & FileGetVersion ( $aList[$i] ) & @Crlf )
Next

#Region ------ Global Variables ------------------------------
FileChangeDir ( @ScriptDir & '\Libraries' )
Global $h_RsvgDll = DllOpen ( @ScriptDir & '\Libraries\librsvg-2-2.dll' )
Global $h_CairoDll = DllOpen ( @ScriptDir & '\Libraries\libcairo-2.dll' )
Global $sPngFilePath = @DesktopDir & '\' & @HOUR & @MIN & @SEC & @MSEC & '.png'
Global $sSvgFilePath, $hRsvg, $pCairoSurface, $pCr
#EndRegion --- Global Variables ------------------------------

FileChangeDir ( @ScriptDir & '\SVG files' )
$sSvgFilePath = FileOpenDialog ( 'Select a Shape', @WorkingDir, 'Vector Graphic (*.svg)', 1+2, '' )
If @error Then Exit

; Open the SVG image file
$hRsvg = _Rsvg_handle_new_from_file ( $sSvgFilePath )
ConsoleWrite ( '!->-- [' & StringFormat ( '%03i', @ScriptLineNumber ) & '] $hRsvg : ' & $hRsvg & @Crlf )

; Get dimensions
$aSize = _Rsvg_handle_get_dimensions ( $hRsvg )
If Not @error Then ConsoleWrite ( '> Width  : ' & $aSize[0] & ', Height : ' & $aSize[1] & @Crlf )

; Create a Surface into which we render the SVG drawing
$pCairoSurface = _Cairo_image_surface_create ( $CAIRO_FORMAT_ARGB32, $aSize[0], $aSize[1] )
ConsoleWrite ( '!->-- [' & StringFormat ( '%03i', @ScriptLineNumber ) & '] $pCairoSurface : ' & $pCairoSurface & @Crlf )

; Create a new Cairo renderer
$pCr = _Cairo_create ( $pCairoSurface )
ConsoleWrite ( '!->-- [' & StringFormat ( '%03i', @ScriptLineNumber ) & '] $pCr : ' & $pCr & @Crlf )
ConsoleWrite ( 'Cairo status after _Cairo_create : ' & _Cairo_status ( $pCr ) & @Crlf )

; Render the SVG into the Cairo buffer
_Rsvg_handle_render_cairo ( $hRsvg, $pCr )
ConsoleWrite ( 'Cairo status after _Rsvg_handle_render_cairo : ' & _Cairo_status ( $pCr ) & @Crlf )

; Save to png
_Cairo_surface_write_to_png ( $pCairoSurface, $sPngFilePath )
ConsoleWrite ( 'Cairo status after _Cairo_surface_write_to_png : ' & _Cairo_status ( $pCr ) & @Crlf )

_Cairo_surface_finish ( $pCairoSurface )
ConsoleWrite ( 'Cairo status after _Cairo_surface_finish : ' & _Cairo_status ( $pCr ) & @Crlf )

_Rsvg_handle_close ( $hRsvg )
ConsoleWrite ( 'Cairo status after _Rsvg_handle_close : ' & _Cairo_status ( $pCr ) & @Crlf )

; Display
_BitmapDisplayInWindowsViewer ( $sPngFilePath )

; Cleanup
_Cairo_destroy ( $pCr )
_Cairo_surface_destroy ( $pCairoSurface )
DllClose ( $h_RsvgDll )
DllClose ( $h_CairoDll )
Exit

Func _BitmapDisplayInWindowsViewer ( $sFilePath )
    If Not FileExists ( $sFilePath ) Then Return SetError ( -1 )
    Run ( 'rundll32 shimgvw.dll,ImageView_Fullscreen ' & $sFilePath )
EndFunc ;==> _BitmapDisplayInWindowsViewer()

Func _Cairo_create ( $pCairoSurface )
    Local $aRet = DllCall ( $h_CairoDll, 'ptr:cdecl', 'cairo_create', 'ptr', $pCairoSurface )
    If @error Then Return SetError ( @error, 0, 0 )
    Return $aRet[0]
EndFunc ;==> _Cairo_create()

Func _Cairo_destroy ( $pCr )
    Local $aRet = DllCall ( $h_CairoDll, 'int:cdecl', 'cairo_destroy', 'ptr', $pCr )
    If @error Then Return SetError ( @error, 0, 0 )
    Return $aRet[0]
EndFunc ;==> _Cairo_destroy()

Func _Cairo_image_surface_create ( $iFormat, $iWidth, $iHeight )
    Local $aRet = DllCall ( $h_CairoDll, 'ptr:cdecl', 'cairo_image_surface_create', 'int', $iFormat, 'int', $iWidth, 'int', $iHeight )
    If @error Then Return SetError ( @error, 0, 0 )
    Return $aRet[0]
EndFunc ;==> _Cairo_image_surface_create()

Func _Cairo_image_surface_create_for_data ( $iFormat, $iWidth, $iHeight, $iStride )
    Local $tStruct = DllStructCreate ( 'byte[' & $iStride*$iHeight & ']' )
    Local $aRet = DllCall ( $h_CairoDll, 'ptr:cdecl', 'cairo_image_surface_create_for_data', 'ptr', DllStructGetPtr ( $tStruct ), 'int', $iFormat, 'int', $iWidth, 'int', $iHeight, 'int', $iStride )
    If @error Then Return SetError ( @error, 0, 0 )
    $tStruct = 0
    Return $aRet[0]
EndFunc ;==> _Cairo_image_surface_create_for_data()

Func _Cairo_status ( $pCr )
    Local $aRet = DllCall ( $h_CairoDll, 'int:cdecl', 'cairo_status', 'ptr', $pCr )
    If @error Then Return SetError ( @error, 0, 0 )
    Switch $aRet[0]
        Case $CAIRO_STATUS_SUCCESS
            Return 'SUCCESS'
        Case $CAIRO_STATUS_NO_MEMORY
            Return 'NO MEMORY'
        Case $CAIRO_STATUS_INVALID_RESTORE
            Return 'INVALID RESTORE'
        Case $CAIRO_STATUS_INVALID_POP_GROUP
            Return 'INVALID POP GROUP'
        Case $CAIRO_STATUS_NO_CURRENT_POINT
            Return 'NO CURRENT POINT'
        Case $CAIRO_STATUS_INVALID_MATRIX
            Return 'INVALID MATRIX'
        Case $CAIRO_STATUS_INVALID_STATUS
            Return 'INVALID STATUS'
        Case $CAIRO_STATUS_NULL_POINTER
            Return 'NULL POINTER'
        Case $CAIRO_STATUS_INVALID_STRING
            Return 'INVALID STRING'
        Case $CAIRO_STATUS_INVALID_PATH_DATA
            Return 'INVALID PATH DATA'
        Case $CAIRO_STATUS_READ_ERROR
            Return 'READ ERROR'
        Case $CAIRO_STATUS_WRITE_ERROR
            Return 'WRITE ERROR'
        Case $CAIRO_STATUS_SURFACE_FINISHED
            Return 'SURFACE FINISHED'
        Case $CAIRO_STATUS_SURFACE_TYPE_MISMATCH
            Return 'SURFACE TYPE MISMATCH'
        Case $CAIRO_STATUS_PATTERN_TYPE_MISMATCH
            Return 'PATTERN TYPE MISMATCH'
        Case $CAIRO_STATUS_INVALID_CONTENT
            Return 'INVALID CONTENT'
        Case $CAIRO_STATUS_INVALID_FORMAT
            Return 'INVALID FORMAT'
        Case $CAIRO_STATUS_INVALID_VISUAL
            Return 'INVALID VISUAL'
        Case $CAIRO_STATUS_FILE_NOT_FOUND
            Return 'FILE NOT FOUND'
        Case $CAIRO_STATUS_INVALID_DASH
            Return 'INVALID DASH'
        Case $CAIRO_STATUS_INVALID_DSC_COMMENT
            Return 'INVALID DSC COMMENT'
        Case $CAIRO_STATUS_INVALID_INDEX
            Return 'INVALID INDEX'
        Case $CAIRO_STATUS_CLIP_NOT_REPRESENTABLE
            Return 'CLIP NOT REPRESENTABLE'
        Case $CAIRO_STATUS_TEMP_FILE_ERROR
            Return 'TEMP FILE ERROR'
        Case $CAIRO_STATUS_INVALID_STRIDE
            Return 'INVALID STRIDE'
        Case $CAIRO_STATUS_FONT_TYPE_MISMATCH
            Return 'FONT TYPE MISMATCH'
        Case $CAIRO_STATUS_USER_FONT_IMMUTABLE
            Return 'USER FONT IMMUTABLE'
        Case $CAIRO_STATUS_USER_FONT_ERROR
            Return 'USER FONT ERROR'
        Case $CAIRO_STATUS_NEGATIVE_COUNT
            Return 'NEGATIVE COUNT'
        Case $CAIRO_STATUS_INVALID_CLUSTERS
            Return 'INVALID CLUSTERS'
        Case $CAIRO_STATUS_INVALID_SLANT
            Return 'INVALID SLANT'
        Case $CAIRO_STATUS_INVALID_WEIGHT
            Return 'INVALID WEIGHT'
        Case $CAIRO_STATUS_INVALID_SIZE
            Return 'INVALID SIZE'
        Case $CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED
            Return 'USER FONT NOT IMPLEMENTED'
        Case $CAIRO_STATUS_DEVICE_TYPE_MISMATCH
            Return 'DEVICE TYPE MISMATCH'
        Case $CAIRO_STATUS_DEVICE_ERROR
            Return 'DEVICE ERROR'
        Case $CAIRO_STATUS_INVALID_MESH_CONSTRUCTION
            Return 'INVALID MESH CONSTRUCTION'
        Case $CAIRO_STATUS_DEVICE_FINISHED
            Return 'DEVICE FINISHED'
        Case $CAIRO_STATUS_LAST_STATUS
            Return 'LAST STATUS'
        Case Else
            Return 'UNKNOW ERROR'
    EndSwitch
EndFunc ;==> _Cairo_status()

Func _Cairo_status_to_string()
    Local $aRet = DllCall ( $h_CairoDll, 'str:cdecl', 'cairo_status_to_string' )
    If @error Then Return SetError ( @error, 0, 0 )
;~  If $aRet[0] = '<unknown error status>' Then Return ''
    Return $aRet[0]
EndFunc ;==> _Cairo_status_to_string()

Func _Cairo_surface_destroy ( $pCairoSurface )
    Local $aRet = DllCall ( $h_CairoDll, 'int:cdecl', 'cairo_surface_destroy', 'ptr', $pCairoSurface )
    If @error Then Return SetError ( @error, 0, 0 )
    Return $aRet[0]
EndFunc ;==> _Cairo_surface_destroy()

Func _Cairo_surface_finish ( $pCairoSurface )
    Local $aRet = DllCall ( $h_CairoDll, 'int:cdecl', 'cairo_surface_finish', 'ptr', $pCairoSurface )
    If @error Then Return SetError ( @error, 0, 0 )
    Return $aRet[0]
EndFunc ;==> _Cairo_surface_finish()

Func _Cairo_surface_write_to_png ( $pCairoSurface, $sFilePath )
    Local $aRet = DllCall ( $h_CairoDll, 'int:cdecl', 'cairo_surface_write_to_png', 'ptr', $pCairoSurface, 'str', $sFilePath )
    If @error Then Return SetError ( @error, 0, 0 )
    Return $aRet[0]
EndFunc ;==> _Cairo_surface_write_to_png()

Func _GetBinaryType ( $sFilePath ) ; by Dougiefresh
    Local $hFile = FileOpen ( $sFilePath, 16 )
    If $hFile = -1 Then Return SetError ( -1, 0, 'Invalid' )
    If BinaryToString ( FileRead ( $hFile, 2 ) ) = 'MZ' Then
        FileSetPos ( $hFile, 60, 0 )
        FileSetPos ( $hFile, Int ( FileRead ( $hFile, 4 ) ) +4, 0 )
        Local $sFileRead = FileRead ( $hFile, 2 )
        FileClose ( $hFile )
        If $sFileRead = '0x6486' Then Return 'AMD64'
        If $sFileRead = '0x4c01' Then Return 'i386'
        If $sFileRead = '0x0002' Then Return 'IA64'
    EndIf
    FileClose ( $hFile )
    Return 'Unknown'
EndFunc ;==> _GetBinaryType()

Func _Rsvg_handle_close ( $hRsvg )
    Local $iError = 0
    Local $aRet = DllCall ( $h_RsvgDll, 'ptr:cdecl', 'rsvg_handle_close', 'ptr', $hRsvg, 'int', $iError )
    If @error Then Return SetError ( @error, 0, 0 )
    If $iError Then Return SetError ( $iError, 0, 0 )
    Return $aRet[0]
EndFunc ;==> _Rsvg_handle_close()

Func _Rsvg_handle_get_dimensions ( $hRsvg )
    Local $aSize[4], $tRsvgDimensionData = DllStructCreate ( 'int width;int height;double em;double ex' )
    Local $aRet = DllCall ( $h_RsvgDll, 'int:cdecl', 'rsvg_handle_get_dimensions', 'ptr', $hRsvg, 'ptr', DllStructGetPtr ( $tRsvgDimensionData ) )
    If @error Then Return SetError ( @error, 0, 0 )
    $aSize[0] = $tRsvgDimensionData.width
    $aSize[1] = $tRsvgDimensionData.height
    $aSize[2] = $tRsvgDimensionData.em
    $aSize[3] = $tRsvgDimensionData.ex
    $tRsvgDimensionData = 0
    Return $aSize
EndFunc ;==> _Rsvg_handle_get_dimensions()

Func _Rsvg_handle_new_from_file ( $sSvgFile )
    If Not FileExists ( $sSvgFile ) Then Return SetError ( -1, 0, 0 )
    Local $iError = 0
    Local $aRet = DllCall ( $h_RsvgDll, 'ptr:cdecl', 'rsvg_handle_new_from_file', 'str', FileGetShortName ( $sSvgFile ), 'int', $iError )
    If @error Then Return SetError ( @error, 0, 0 )
    If $iError Then Return SetError ( $iError, 0, 0 )
    Return $aRet[0]
EndFunc ;==> _Rsvg_handle_new_from_file()

Func _Rsvg_handle_render_cairo ( $hRsvg, $pCr )
    Local $aRet = DllCall ( $h_RsvgDll, 'bool:cdecl', 'rsvg_handle_render_cairo', 'ptr', $hRsvg, 'ptr', $pCr )
    If @error Then Return SetError ( @error, 0, 0 )
    Return $aRet[0] ; Returns TRUE if drawing succeeded.
EndFunc ;==> _Rsvg_handle_render_cairo()

Func _Rsvg_init() ; deprecated since version 2.36 and should not be used in newly-written code.
    Local $aRet = DllCall ( $h_RsvgDll, 'int:cdecl', 'rsvg_init' )
    If @error Then Return SetError ( @error, 0, 0 )
    Return $aRet[0]
EndFunc ;==> _Rsvg_init()

Script and files are available in the downloads Section

 

Edited by wakillon

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Link to comment
Share on other sites

7 hours ago, wakillon said:

Convert SVG file to PNG using Cairo and rsvg libraries (and their imports)

I changed

If $CmdLine[0] = 1 Then
    If Not FileExists($CmdLine[1]) Then Exit 1
    $sSvgFilePath = $CmdLine[1]
    $sPngFilePath = $sSvgFilePath & ".png"
Else
    FileChangeDir(@ScriptDir & '\SVG files') ; original line
    $sSvgFilePath = FileOpenDialog('Select a Shape', @WorkingDir, 'Vector Graphic (*.svg)', 1 + 2, '') ; original line
    If @error Then Exit 1 ; original line
    $sPngFilePath = $sSvgFilePath & ".png" ; I'd like to see the file to compare sizes.
EndIf

to have a SVG viewer of sorts.

got an ICO and compiled it.

Then I decided to move the folder and found that some DLLs are open along with some SVG and some PNG too and won't delete.

Could you look into closing the open files ? Thanks.

 

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...