As part of our ongoing work to improve the accessibility rating of our site, we needed to address the issue of lots of images not having ALT Tags in the media library. To achieve our goal I tested out the script below, before pointing it at the 100’s of images in need of attention!
All credit to Adam Seabridge, who provided the solution and write up on the necessary configs required to get it working:
Adding it here for my own reference more than anything else.
$visionUrl = 'xxx'
$visionApiKey = 'xxx'
$visionFeatures = 'Description,Tags,Categories'
$rootPathOfImages = "/sitecore/media library/"
$testMode = $false
$secondsToWaitOnLimitError = 60
$successCount = 0
$errorCount = 0
$errorList = ""
$date = Get-Date
$formattedDate =$date.tostring('dd-mmm-yyyy-hhmmss')
$csvOutputFilePath = "C:\temp\Missing-Alt-Text-Report-$($formattedDate).csv"
$createCsv = $true
$csvResults = @()
# List of template ids to exclude from processing
$excludedTemplateIds = @(
"{FE5DD826-48C6-436D-B87A-7C4210C7413B}", #media folder
"{0603F166-35B8-469F-8123-E8D87BEDC171}", #pdf
"{16692733-9A61-45E6-B0D4-4C0C06F8DD3C}", #doc
"{7BB0411F-50CD-4C21-AD8F-1FCDE7C3AFFE}", #docx
"{962B53C4-F93B-4DF9-9821-415C867B8903}", #unversioned file
"{E76ADBDF-87D1-4FCB-BA71-274F7DBF5670}", #unversioned movie
"{4F4A3A3B-239F-4988-98E1-DA3779749CBC}" #unversioned zip
)
# List of folder ids to exclude from processing
$excludedFolderIds = @(
"{23FAF40D-6700-480C-BCAD-92E23F60634C}" #wffm folder
)
if($testMode){
Write-Host -Foreground Yellow "Running in TEST MODE, no Alt Text will be set."
}
Write-Host "Finding Images with Missing Alt Text in root folder: $($rootPathOfImages) ..."
cd $rootPathOfImages
$images = Get-ChildItem -Recurse . | Where-Object {
($excludedTemplateIds -notcontains $_.TemplateId) `
-and ($excludedFolderIds -notcontains $_.ID) `
-and ($excludedFolderIds -notcontains $_.Parent.ID) `
-and ($excludedFolderIds -notcontains $_.Parent.Parent.ID) `
-and ($excludedFolderIds -notcontains $_.Parent.Parent.Parent.ID) `
-and ([string]::IsNullOrWhiteSpace($_.Fields["Alt"].Value)) `
}
Write-Host -Foreground Green "$($images.Count) Images Found With Missing Alt Text"
$result = @()
$counter = 0
$mediaUrloptions = New-Object Sitecore.Resources.Media.MediaUrlOptions
$mediaUrloptions.Width = 1000
$mediaUrloptions.UseItemPath = 0
foreach ($image in $images)
{
$counter+=1
# Sitecore
try{
# Reading the binary of the image so that we could send it to the Computer Vision API
Write-Host "Reading Image $($counter) of $($images.Count): $($image.ID) - $($image.Name) ...`n"
$id = $image.ID
$name = $image.Name
$displayName = $image.Fields["__Display name"].Value
$path = $image.ItemPath
$success = $False
$imageUrl = [Sitecore.Resources.Media.MediaManager]::GetMediaUrl($image, $mediaUrloptions)
$url = $imageUrl -replace '/sitecore/shell', '' #fix to request image from published Site
$url = "https://mysite.co.uk" + $url
Write-Host "Downloading image: $url ...`n"
$webClient = New-Object System.Net.WebClient
$file = $webClient.DownloadData($url)
}
catch [System.Net.WebException]
{
$HttpStatusCode = $_.Exception.Response.StatusCode.value__
$HttpStatusDescription = $_.Exception.Response.StatusDescription
Write-Host -Foreground Red "Error Downloading Image: $($HttpStatusCode) - Http Status Description: $($HttpStatusDescription)"
$errorCount +=1
$errorList = $errorList + "$($id) - $($name) `n"
continue
}
catch
{
Write-Host -Foreground Red "Error Downloading Image: $($id) - $($name) - Error Message: $($_.Exception.Message)"
continue
}
# Computer Vision API
do
{
try
{
if($file){
Write-Host "Calling Endpoint: $($visionUrl)?visualFeatures=$($visionFeatures)&language=en"
# Calling the Computer Vision API
$response = Invoke-WebRequest `
-Uri "$($visionUrl)?visualFeatures=$($visionFeatures)&language=en" `
-Body $file `
-ContentType "application/octet-stream" `
-Headers @{"Ocp-Apim-Subscription-Key" = "$($visionApiKey)"} `
-Method 'Post' `
-ErrorAction Stop `
-UseBasicParsing | ConvertFrom-Json
# Tracking what image the response should be attached to
$response | Add-Member -Name "id" `
-MemberType NoteProperty `
-Value "$($image.ID.ToShortID())"
$altText = $response.description.captions[0].text
Write-Host "Image Processed: $($image.Paths.FullPath)`n`n"
if($altText){
}
else{
$altText=$image.Name
}
if($altText){
if($testMode){
Write-Host -Foreground Cyan "Alt Text Not set as in TEST MODE, but would be:" $altText
}
else
{
# update Alt tag on image
$image.Editing.BeginEdit()
$image.Fields["Alt"].Value = $altText
$image.Editing.EndEdit()
Write-Host -Foreground Cyan "Alt Text Set To:" $altText
Write-Host "----------------------------------`n`n"
}
$result += $response
$csvProperties = @{
ID = $id
Name = $name
DisplayName = $displayName
Path = $path
AltText = $altText
}
$csvResults += New-Object psobject -Property $csvProperties;
$success = $True
$successCount +=1
}
else{
Write-Host -Foreground Yellow "No Alt Text Returned For Image: $($id) - $($name)"
$errorCount +=1
$errorList = $errorList + "$($id) - $($name) `n"
break
}
}
else{
Write-Host -Foreground Red "No Image Found In Sitecore For: $($id) - $($name)"
$errorCount +=1
$errorList = $errorList + "$($id) - $($name) `n"
break
}
}
catch [System.Net.WebException]
{
$HttpStatusCode = $_.Exception.Response.StatusCode.value__
$HttpStatusDescription = $_.Exception.Response.StatusDescription
Write-Host -Foreground Red "Error Calling Computer Vision API: $($HttpStatusCode) - Http Status Description: $($HttpStatusDescription)"
if($HttpStatusCode -eq "429"){
Write-Host -Foreground Magenta "Exceeded Computer Vision API limit. Waiting for $($secondsToWaitOnLimitError) seconds..."
Start-Sleep -s $secondsToWaitOnLimitError
Write-Host -Foreground Green "Resuming now..."
}
else{
$errorCount +=1
$errorList = $errorList + "$($id) - $($name) `n"
break
}
}
catch
{
Write-Host -Foreground Red "Error processing Image: $($id) - $($name) - Error Message: $($_.Exception.Message)"
break
}
}
while ($success -ne $True)
}
if($testMode){
Write-Host -Foreground Yellow "TEST MODE complete."
}
Write-Host -Foreground Green "$($successCount) Images Successfully Processed"
Write-Host "$($errorCount) Errors Processing Images"
if($errorCount -gt 0){
Write-Host -Foreground Red "Errors List"
Write-Host -Foreground Red "-----------------------------"
Write-Host -Foreground Red $errorList
}
if($createCsv -and $successCount -gt 0){
Write-Host "Saving Report of Alt Text to: ${csvOutputFilePath}"
$csvResults | Select-Object ID,Name,DisplayName,Path,AltText | Export-Csv -notypeinformation -Path $csvOutputFilePath
}
#Write-Host ($result | ConvertTo-Json -Depth 5)