Image AI 5

Scripting

Learn how to use Image AI with scripts.

Client Script to Trigger Calculating Image Variant Clips

The following client script uses Image AI to calculate image variant clips, and sets them in the image document in the current editor. The script can be run manually via the editor's toolbar, and it can run automatically on every save.

In addition to the script's code, you need to set additional settings as follows:

  • The document source must be "Current editor".
  • If a toolbar button for manual runs is desired, set a menu text.
  • If the script should run automatically at saving a new image document, set the trigger to "Save".
  • In the list of document types, select your image document type.

You also need to modify IMAGE_AI_URI and IGNORE_USERNAME in the script:

  • IMAGE_AI_URI - The base URL of the Image AI service.
  • IGNORE_USERNAME - The script will not run if this user has started the script. This is useful if the script is running on every save, but it shouldn't run if a document is being imported via the importer.
def IMAGE_AI_URI = 'http://imageai.example.com:8080'
def IGNORE_USERNAMES = ['importer']


class Response {
    CropHint[] cropHints
    String cropHintsComment
}

class CropHint {
    Rectangle rectangle
}

class Rectangle {
    int x
    int y
    int width
    int height
}


if (IGNORE_USERNAMES.contains(sophoraClient.username)) {
    return
}

def doc = context.document

if (!context.isUpdatable(doc)) {
    return
}

if (context.trigger != ClientScriptTrigger.DIRECT && doc.UUID != null) {
    return
}

def variantNodes = doc.getNodesByName('sophora-extension:imagedata')

def originalVariantNode = variantNodes.find { it.getString('sophora-extension:imagetype') == 'original' }
if (!originalVariantNode) {
    return
}

def originalBinary = originalVariantNode.getBinaryData('sophora-extension:binarydata')
if (!originalBinary) {
    return
}

def originalWidth = originalVariantNode.getLong('sophora-extension:width')
def originalHeight = originalVariantNode.getLong('sophora-extension:height')
def originalAspectRatio = (double) originalWidth / (double) originalHeight

def siteUUID = doc.structureInfo.siteUUID

def siteVariants = sophoraClient.getImageVariantsForSite(siteUUID)
    .findAll { it.name != 'original' }
    .findAll { it.getStateForSite(siteUUID) == com.subshell.sophora.api.structure.ImageVariant.State.ACTIVE }

def aspectRatios = siteVariants.collect {
    it.width != null && it.height != null ?
        (double) it.width / (double) it.height :
        originalAspectRatio
}

def clientBuilder = context.getHttpClientBuilder()
    .userAgent('Image AI Generate AI Variants')
    .timeout(java.time.Duration.ofSeconds(30))

def response
def error = false

context.showBusyWhile('Calculate image variants', {
    try (def client = clientBuilder.build()) {
        def restClient = new HttpClientRestWrapper(client)
    
        def request = [
            image: java.util.Base64.encoder.encodeToString(originalBinary.bytes),
            cropHints: [
                aspectRatios: aspectRatios
            ]
        ]

        response = restClient.post(IMAGE_AI_URI + '/rest/v1/image-ai', request, Response.class)
    } catch (Exception e) {
        error = true
    }
})

if (error) {
    context.dialog().showMessage('An error has occurred. Please try again later.')
    return
}

response.cropHints.eachWithIndex { cropHint, cropHintIdx ->
    def variantName = siteVariants[cropHintIdx].name
    def variantNode = variantNodes.find { it.getString('sophora-extension:imagetype') == variantName }
    
    variantNode.setLong('sophora-extension:clipX', cropHint.rectangle.x)
    variantNode.setLong('sophora-extension:clipY', cropHint.rectangle.y)
    variantNode.setLong('sophora-extension:width', cropHint.rectangle.width)
    variantNode.setLong('sophora-extension:height', cropHint.rectangle.height)
    variantNode.setBoolean('sophora-extension:disabled', false)
}

def historyItem = doc.addNode('sophora-extension:imageAIHistory', 'sophora-extension-nt:imageAIHistoryItem')
historyItem.setDate('sophora-extension:eventDate', java.util.GregorianCalendar.instance)
historyItem.setString('sophora-extension:description', response.cropHintsComment)

context.updateDocument(doc)

Last modified on 7/25/23

The content of this page is licensed under the CC BY 4.0 License. Code samples are licensed under the MIT License.

Icon