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.
This script requires Sophora Core >=5.10.0.
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)