We use cookies to improve your experience.
By your continued use of this site you accept such use.
For more details please see our privacy policy and cookies policy.

Script Repository

Optimize User Photo

February 24, 2021 Views: 2888

The script optimizes uploaded user photos to fit within the limit set by Active Directory (100 kilobytes) and best view in Adaxes (80x80 pixels).

To run the script automatically, create a business rule triggering Before updating a user and add the If Picture property has changed condition.

Parameters:

  • $maxWidth - Specifies the maximum width of the photo in pixels.
  • $maxHeight - Specifies the maximum height of the photo in pixels.
Edit Remove
PowerShell
$maxWidth = 80 # TODO: modify me
$maxHeight = 80 # TODO: modify me

function CheckFileSizeAndSave ($filePath, $quality, $imageFormat, $imageCodecInfo, $picture)
{
    if ($quality -lt 0)
    {
        DeleteTmpFile $filePath
        return
    }
    
    # Set encoder settings for image quality 
    $encoderParams = New-Object System.Drawing.Imaging.EncoderParameters(1)
    $encoder = [System.Drawing.Imaging.Encoder]::Quality
    $encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter($encoder, $quality)
    
    # Save file
    $picture.Save($filePath, $imageCodecInfo, $($encoderParams))
    
    # Check file size
    $fileSize = (Get-Item $filePath).Length / 1kb
    if ($fileSize -lt 100)
    {
        return
    }
    else
    {
        $quality = $quality - 10
        CheckFileSizeAndSave $filePath $quality $imageFormat $imageCodecInfo $picture
    }
}

function DeleteTmpFile ($filePath)
{
    [System.IO.File]::Delete($filePath)
}

function UpdateUserPhoto ($tmpFilePath)
{
    if (!(Test-Path $tmpFilePath))
    {
        $Context.Cancel("Automatic photo resize failed.") # TODO: modify me
        return
    }
    
    # Update the thumbnailPhoto attribute
    $thumbnailPhotoBytes = [System.IO.File]::ReadAllBytes($tmpFilePath)
    $Context.SetModifiedPropertyValue("thumbnailPhoto", $thumbnailPhotoBytes)
    
    # Delete the temporary file
    DeleteTmpFile $tmpFilePath
}

# Get the picture
$thumbnailPhotoBytes = $Context.GetModifiedPropertyValue("thumbnailPhoto")
if ([System.String]::IsNullOrEmpty($thumbnailPhotoBytes))
{
    return # The thumbnailPhoto attribute is empty
}

try
{
    $original = [System.Drawing.Image]$thumbnailPhotoBytes
    $originalWidth = $original.Width
    $originalHeight = $original.Height
    
    # Check original size
    $tmpFilePath = [System.IO.Path]::GetTempFileName()
    $imageFormat = "System.Drawing.Imaging.ImageFormat" -as [type]
    $imageCodecInfo = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | where {$_.MimeType -eq 'image/jpeg'}
    if (($originalHeight -gt $maxHeight) -or ($originalWidth -gt $maxWidth))
    {
        # Calculate the new size, preserve ratio
        $ratioX = $maxWidth / $originalWidth
        $ratioY = $maxHeight / $originalHeight
        $ratio = $ratioY
        if ($ratioX -le $ratioY)
        {
            $ratio = $ratioX
        }
       
        # Resize the picture
        $newPicture = $original.GetThumbnailImage($originalWidth * $ratio, $originalHeight * $ratio, $null, [intptr]::Zero)
        CheckFileSizeAndSave $tmpFilePath 100 $imageFormat $imageCodecInfo $newPicture
        if (!(Test-Path $tmpFilePath))
        {
            $Context.Cancel("Automatically resize photos failed.")
            return
        }
        
        UpdateUserPhoto $tmpFilePath
    }
    else
    {
        CheckFileSizeAndSave $tmpFilePath 100 $imageFormat $imageCodecInfo $original
        UpdateUserPhoto $tmpFilePath
    }
}
finally
{
    # Release resources
    if ($original) { $original.Dispose() }
    if ($newPicture) { $newPicture.Dispose() }
}
Comments 4
avatar
mike Aug 19, 2020
Is there any way to get this working with the import photo script below?

https://www.adaxes.com/script-repository/import-photos-for-users-in-organizational-unit-s388.htm
avatar
Support Aug 20, 2020

Hello Mike,

Yes, it is possible. In the Import photos for users in Organizational Unit script, you will need to replace this line


$user = $Context.BindToObject($searchResult.AdsPath)

with the following one:

$user = $Context.BindToObjectEx($searchResult.AdsPath, $True)

and use the Optimize User Photo script in a Business Rule as described. In this case, all modifications made by the import script will go through Adaxes pipeline and trigger corresponding Business Rules.

If this is not what you need, please, describe the desired behaviour in all the possible details with live examples.

avatar
Boris May 08, 2023
How to modify this script, to get the 80x80 as fix value not as a max value ?
avatar
Support May 08, 2023
Hello Boris,

Sorry for the confusion, but we are not sure what exactly you mean. Please, describe the desired behaviour in all the possible details with live examples.
Leave a comment
Loading...

Got questions?

Support Questions & Answers