How can I replace all images in html file with my base64 codes? (Powershell)

I am using a software called Belarc Avisor which provides html output of all hardware details including licenses / keys / serials of installed software in html format. I usually create this report from this software either on a new PC or before formatting the PC. However, the exported chrome file uses a separate folder for images and I need a standalone html file with all the details and images (including the html report css styles).

Currently I had to replace the images in notepad ++ with my base64 code which was generated from the online site. I'm looking for an alternative way to do this in any batch script or Powershell. I found two questions on stackoverflow { q1 }, { q2 } and { blog-post } and enter the following code:

    $original_file = 'path\filename.html'
    $destination_file =  'path\filename.new.html'
    (Get-Content $original_file) | Foreach-IMG-SELECTOR-Object {
        $path = $_ SOURCE-TAG-SELECTOR `
        -replace $path, [convert]::ToBase64String((get-content $path -encoding byte))
    } | Set-Content $destination_file

      

Q Foreach-Object

, perhaps the object can be selected by the html img tag? If so, then base64 conversion will be pretty easy!

to convert to base64, line:   [convert]::ToBase64String((get-content $path -encoding byte))

where $path

is the path to the image. Can be simply copied from the tag <img src="">

.

I just read that Windows 10 has Powershell 5.0, so I thought I could create a batch file to create it.

So, if tags img

and attribute src

can be selected, they only need to be replaced with base64 tags.

Modified version Answer

The answer provided by Alexendar is not valid because during the loop the attribute-value is set to #Document while it should be set to the current node. After searching the web and reading the Powershell console, I found that this can be solved by selecting the current node via XPath. Here's a modified answer:

Import-Module -Name "C:\HtmlAgilityPack.1.4.6\Net40\HtmlAgilityPack.dll" # Change to your actual path

function Convert_to_Base64 ($sImgFile)
{
#$sImgFile = "C:\image.jpg" # Change to your actual path
$oImgFormat = [System.Drawing.Imaging.ImageFormat]::Gif # Change to your format

$oImage = [System.Drawing.Image]::FromFile($sImgFile)
$oMemoryStream = New-Object -TypeName System.IO.MemoryStream
$oImage.Save($oMemoryStream, $oImgFormat)
$cImgBytes = [Byte[]]($oMemoryStream.ToArray())
$sBase64 = [System.Convert]::ToBase64String($cImgBytes)

$sBase64
}


$sInFile = "C:\Users\USER\Desktop\BelarcAdvisor win10\Belarc Advisor Computer Profile.html" # Change to your actual path
$sOutFile = "D:\Win10-Belarc.html" # Change to your actual path
$sPathBase = "C:\Users\USER\Desktop\BelarcAdvisor win10\"

$sXpath = "//img"
$sAttributeName = "src"

$oHtmlDocument = New-Object -TypeName HtmlAgilityPack.HtmlDocument
$oHtmlDocument.Load($sInFile)
$oHtmlDocument.DocumentNode.SelectNodes($sXpath) | ForEach-Object {
    # If you need to download the image, here how you can extract the image
    # URI (note that it may be realtive, not absolute):

    $sVarXPath = $_ #To get the Current Node and then later get Attributes + XPathXPath from this node variable.

    #$sVarXPath.XPath

    $sSrcPath = $sVarXPath.get_Attributes() `
        | Where-Object { $_.Name -eq $sAttributeName } `
        | Select-Object -ExpandProperty "Value"
    # Assembling absolute URI:
    $sUri = Join-Path -Path $sPathBase -ChildPath $sSrcPath.substring(2) #substring for "./" in the src string of the img in subfolder.
    #$sUri
    # Now you can d/l the image: Invoke-WebRequest -Uri $sUri
    #[System.Drawing.Image]::FromFile($sUri)

    # Put your Base64 conversion code here.
    $sBase64 = Convert_to_Base64($sUri)

    $sSrcValue = "data:image/png;base64," + $sBase64
    $oHtmlDocument.DocumentNode.SelectNodes($sVarXPath.XPath).SetAttributeValue($sAttributeName, $sSrcValue)
    #$oHtmlDocument.DocumentNode.SelectNodes($sVarXPath.XPath).GetAttributeValue($sAttributeName, "")
}

#$oHtmlDocument.DocumentNode.SelectNodes($sXpath) | foreach-object { write-output $_ }

$oHtmlDocument.Save($sOutFile)

      

+3


source to share


2 answers


It's pretty easy. You can use HtmlAgilityPack to parse HTML:

Import-Module -Name "C:\HtmlAgilityPack.dll" # Change to your actual path

$sInFile = "E:\Temp\test.html" # Change to your actual path
$sOutFile = "E:\temp\test1.html" # Change to your actual path
$sUriBase = "http://example.com/" # Change to your actual URI base

$sXpath = "//img"
$sAttributeName = "src"

$oHtmlDocument = New-Object -TypeName HtmlAgilityPack.HtmlDocument
$oHtmlDocument.Load($sInFile)
$oHtmlDocument.DocumentNode.SelectNodes($sXpath) | ForEach-Object {
    # If you need to download the image, here how you can extract the image
    # URI (note that it may be realtive, not absolute):
    $sSrcPath = $_.get_Attributes() `
        | Where-Object { $_.Name -eq $sAttributeName } `
        | Select-Object -ExpandProperty "Value"
    # Assembling absolute URI:
    $sUri = $sUriBase + $sSrcPath
    # Now you can d/l the image: Invoke-WebRequest -Uri $sUri


    # Put your Base64 conversion code here.
    $sBase64 = ...

    $sSrcValue = "data:image/png;base64," + $sBase64
    $_.SetAttributeValue($sAttributeName, $sSrcValue)
}

$oHtmlDocument.Save($sOutFile)

      



Converting image file to Base64 string :

$sImgFile = "C:\image.jpg" # Change to your actual path
$oImgFormat = [System.Drawing.Imaging.ImageFormat]::Jpeg # Change to your format

$oImage = [System.Drawing.Image]::FromFile($sImgFile)
$oMemoryStream = New-Object -TypeName System.IO.MemoryStream
$oImage.Save($oMemoryStream, $oImgFormat)
$cImgBytes = [Byte[]]($oMemoryStream.ToArray())
$sBase64 = [System.Convert]::ToBase64String($cImgBytes)

      

+4


source


Partial answer here, but I was able to do the conversion from a single image file to an output URI encoded text file in just one line:

"data:image/png;base64," + [convert]::tobase64string([io.file]::readallbytes(($pwd).path + "\\image.png")) | set-content -encoding ascii "image.txt"



(Note that the encoding of the output file seems to matter.)

This is mainly a post because this is what came up in my web search and also makes it easy to convert in Alexander's answer.

+1


source







All Articles