You are here:
Sample Custom Class To Retrieve Images
You can retrieve an image using custom logic with a custom class implementation. Instead of uploading an image to files, or static resources, you can use custom logic to retrieve an image using an image ID.
A custom implementation uses this token format:
"IMG_imageToken": { "width": 120, "height": 160, "src": "0000x00000x00xxxx"}Here's an example of a custom class to retrieve images.
global with sharing class ImageBlobGenerator implements <namespace>.VlocityOpenInterface {
private static final Integer MAXIMUM_SIZE_ALLOWED_PER_REQUEST = 3500000;
global Boolean invokeMethod(
String methodName,
Map<String, Object> input,
Map<String, Object> output,
Map<String, Object> options) {
Boolean success = false;
System.debug('invokeMethod:methodName -> ' + methodName);
System.debug('invokeMethod:input-> ' + input);
if (methodName == 'getImageContentBlob')
{
success = getImageContentBlob(input, output);
}
else
{
logger.err('Unsupported method: ' + methodName);
}
System.debug('invokeMethod:success -> ' + success);
return success;
}
global static Boolean getImageContentBlob(Map<String, Object> input, Map<String, Object> output) {
List<String> imageList = (List<String>)input.get('imageKeyList');
Map<String, Integer> sizeMap = fetchSizeForImages(imageList);
List<String> imagesChunk = getChunkForBlobConversion(imageList, sizeMap);
if(imagesChunk.size() != imageList.size()) {
output.put('hasMoreData', true);
output.put('nextChunkStartIndex', imagesChunk.size());
}
Map<String, String> imageContentMap = getImageDataUriFromIds(imagesChunk);
output.put('imageContentMap', imageContentMap);
return true;
}
private static Map<String, Integer> fetchSizeForImages(List<Id> sObjectIds) {
Map<String, Integer> imageSizeMap = new Map<String, Integer>();
String sobjectType = sObjectIds[0].getSObjectType().getDescribe().getName();
String query='';
if(sobjectType == 'ContentDocument') {
query = 'SELECT ContentDocumentId, ContentSize FROM ContentVersion WHERE ContentDocumentId IN :sObjectIds';
List<ContentVersion> cvList = Database.query(query);
if(cvList == null) {
return imageSizeMap;
}
for(ContentVersion obj: cvList) {
imageSizeMap.put(String.valueOf(obj.get('ContentDocumentId')), (Integer)obj.get('ContentSize'));
}
return imageSizeMap;
}
query = 'SELECT Id, BodyLength FROM '+ sobjectType +' WHERE Id =:sObjectIds';
List<SObject> sObjs = Database.query(query);
if(sObjs == null) {
return imageSizeMap;
}
for(SObject obj: sObjs) {
imageSizeMap.put(String.valueOf(obj.get('Id')), (Integer)obj.get('BodyLength'));
}
return imageSizeMap;
}
private static List<String> getChunkForBlobConversion(List<String> imageIdList, Map<String, Integer> sizeMap) {
List<String> result = new List<String>();
Integer totalSizeSoFar = 0;
Integer sizeLimit = (MAXIMUM_SIZE_ALLOWED_PER_REQUEST * 3) / 4;
for(String imageId: imageIdList) {
totalSizeSoFar += sizeMap.get(imageId) != null ? sizeMap.get(imageId) : 0;
if(totalSizeSoFar <= sizeLimit) {
result.add(imageId);
} else {
break;
}
}
return result;
}
private static Map<String, String> getImageDataUriFromIds(List<Id> sObjectIds) {
Map<String, String> imageBlobMap = new Map<String, String>();
String sobjectType = sObjectIds[0].getSObjectType().getDescribe().getName();
system.debug('#### sobjectType = ' + sobjectType);
String query='';
if(sobjectType == 'ContentDocument')
{
query = 'SELECT ContentDocumentId, VersionData, FileType FROM ContentVersion WHERE ContentDocumentId IN :sObjectIds';
system.debug('Heap Size after query: ' + Limits.getHeapSize());
List<ContentVersion> cvList = Database.query(query);
if(cvList == null) {
return imageBlobMap;
}
for(ContentVersion obj: cvList) {
imageBlobMap.put(String.valueOf(obj.get('ContentDocumentId')), generateDataUri((Blob)obj.get('VersionData'), obj.get('FileType')));
}
return imageBlobMap;
}
query = 'SELECT Id, Body, ContentType FROM '+ sobjectType +' WHERE Id =:sObjectIds';
system.debug('#### query = ' + query);
List<SObject> sObjs = Database.query(query);
if(sObjs == null){
return imageBlobMap;
}
for(SObject obj: sObjs) {
imageBlobMap.put(String.valueOf(obj.get('Id')), generateDataUri((Blob)obj.get('Body'), obj.get('ContentType')));
}
return imageBlobMap;
}
private static String generateDataUri(Blob content, Object type) {
return 'data:' + type + ';base64,' + EncodingUtil.base64Encode(content);
}
}
