Utveckla en Asset Compute-arbetare
Asset Compute-arbetare är kärnan i ett Asset Compute-projekt och tillhandahåller anpassade funktioner som utför, eller koordinerar, arbetet som utförs på en resurs för att skapa en ny rendering.
Asset Compute-projektet genererar automatiskt en enkel arbetare som kopierar resursens ursprungliga binärfil till en namngiven återgivning, utan några omformningar. I den här självstudiekursen ska vi modifiera arbetaren för att göra en intressantare rendering som visar Asset Compute arbetares styrka.
Vi kommer att skapa en Asset Compute-arbetare som genererar en ny vågrät bildåtergivning, som omfattar tomt utrymme till vänster och höger om resursåtergivningen med en oskarp version av resursen. Bredden, höjden och oskärpan för den slutliga återgivningen parametriseras.
Logiskt flöde för ett anrop till en Asset Compute-arbetare
Asset Compute-arbetare implementerar Asset Compute SDK-arbets-API-kontraktet i funktionen renditionCallback(...) som är begreppsmässigt:
- Indata: En AEM-resurs ursprungliga binära parametrar och parametrar för Bearbetningsprofil
- Utdata: En eller flera återgivningar som ska läggas till i AEM-resursen
-
AEM Author-tjänsten anropar Asset Compute-arbetaren och anger resursens (1a) ursprungliga binärfil (
sourceparameter) och (1b) parametrar som definierats i Bearbetningsprofil (rendition.instructionsparameter). -
Asset Compute SDK ordnar körningen av den anpassade Asset Compute-metadataarbetarens
renditionCallback(...)-funktion, vilket genererar en ny binär återgivning baserat på resursens ursprungliga binära (1a) och eventuella parametrar (1b).- I den här självstudiekursen skapas återgivningen"i arbete", vilket innebär att arbetaren komponerar återgivningen, men källbinärfilen kan även skickas till andra webbtjänstAPI:er för att återge återgivningen.
-
Asset Compute-arbetaren sparar den nya återgivningens binära data till
rendition.path. -
Binära data som skrivs till
rendition.pathöverförs via Asset Compute SDK till AEM Author Service och visas som (4a) en textåtergivning och (4b) beständig till objektets metadatanod.
Diagrammet ovan beskriver Asset Compute utvecklarrelaterade problem och det logiska flödet till Asset Compute arbetaranrop. På grund av nyfikenheten finns de interna detaljerna för körning av Asset Compute, men endast de offentliga API-kontrakten för Asset Compute SDK kan vara beroende av.
Anatomi för en arbetare
Alla Asset Compute-arbetare följer samma grundläggande struktur och in-/utdatakontrakt.
'use strict';
// Any npm module imports used by the worker
const { worker, SourceCorruptError } = require('@adobe/asset-compute-sdk');
const fs = require('fs').promises;
/**
Exports the worker implemented by a custom rendition callback function, which parametrizes the input/output contract for the worker.
+ `source` represents the asset's original binary used as the input for the worker.
+ `rendition` represents the worker's output, which is the creation of a new asset rendition.
+ `params` are optional parameters, which map to additional key/value pairs, including a sub `auth` object that contains Adobe I/O access credentials.
**/
exports.main = worker(async (source, rendition, params) => {
// Perform any necessary source (input) checks
const stats = await fs.stat(source.path);
if (stats.size === 0) {
// Throw appropriate errors whenever an erring condition is met
throw new SourceCorruptError('source file is empty');
}
// Access any custom parameters provided via the Processing Profile configuration
let param1 = rendition.instructions.exampleParam;
/**
Perform all work needed to transform the source into the rendition.
The source data can be accessed:
+ In the worker via a file available at `source.path`
+ Or via a presigned GET URL at `source.url`
**/
if (success) {
// A successful worker must write some data back to `renditions.path`.
// This example performs a trivial 1:1 copy of the source binary to the rendition
await fs.copyFile(source.path, rendition.path);
} else {
// Upon failure an Asset Compute Error (exported by @adobe/asset-compute-commons) should be thrown.
throw new GenericError("An error occurred!", "example-worker");
}
});
/**
Optionally create helper classes or functions the worker's rendition callback function invokes to help organize code.
Code shared across workers, or to complex to be managed in a single file, can be broken out across supporting JavaScript files in the project and imported normally into the worker.
**/
function customHelperFunctions() { ... }
Öppnar arbetarens index.js
- Kontrollera att Asset Compute-projektet är öppet i VS Code
- Navigera till mappen
/actions/worker - Öppna filen
index.js
Det här är den JavaScript-fil för arbetaren som vi ska ändra i den här självstudiekursen.
Installera och importera stödda npm-moduler
Asset Compute-projekt är Node.js-baserade och drar nytta av det robusta ekosystemet för npm-modulen. För att kunna utnyttja npm-moduler måste vi först installera dem i vårt Asset Compute-projekt.
I den här arbetaren använder vi jimp för att skapa och ändra återgivningsbilden direkt i Node.js-koden.
-
Öppna kommandoraden i roten av ditt Asset Compute-projekt (detta kan göras i VS-koden via Terminal > New Terminal) och kör kommandot:
code language-none $ npm install jimp -
Importera modulen
jimptill arbetskoden så att den kan användas via JavaScript-objektetJimp.
Uppdaterarequire-direktiven högst upp i arbetarensindex.jsför att importeraJimp-objektet från modulenjimp:code language-javascript 'use strict'; const Jimp = require('jimp'); const { worker, SourceCorruptError } = require('@adobe/asset-compute-sdk'); const fs = require('fs').promises; exports.main = worker(async (source, rendition, params) => { // Check handle a corrupt input source const stats = await fs.stat(source.path); if (stats.size === 0) { throw new SourceCorruptError('source file is empty'); } // Do work here });
Läsa parametrar
Asset Compute-arbetare kan läsa in parametrar som kan skickas via Bearbeta profiler som definierats i tjänsten AEM as a Cloud Service Author. Parametrarna skickas till arbetaren via objektet rendition.instructions.
Dessa kan läsas genom åtkomst till rendition.instructions.<parameterName> i arbetskoden.
Här läser vi i den konfigurerbara återgivningens SIZE, BRIGHTNESS och CONTRAST med standardvärden om ingen har angetts via Bearbetningsprofilen. Observera att renditions.instructions skickas som strängar när de anropas från AEM as a Cloud Service Bearbetningsprofiler, så se till att de omvandlas till rätt datatyper i arbetskoden.
'use strict';
const Jimp = require('jimp');
const { worker, SourceCorruptError } = require('@adobe/asset-compute-sdk');
const fs = require('fs').promises;
exports.main = worker(async (source, rendition, params) => {
const stats = await fs.stat(source.path);
if (stats.size === 0) {
throw new SourceCorruptError('source file is empty');
}
// Read in parameters and set defaults if parameters are provided
// Processing Profiles pass in instructions as Strings, so make sure to parse to correct data types
const SIZE = parseInt(rendition.instructions.size) || 800;
const CONTRAST = parseFloat(rendition.instructions.contrast) || 0;
const BRIGHTNESS = parseFloat(rendition.instructions.brightness) || 0;
// Do work here
}
Utlösande fel errors
Asset Compute-arbetare kan stöta på situationer som leder till fel. Adobe Asset Compute SDK innehåller en serie fördefinierade fel som kan genereras när sådana situationer uppstår. Om ingen specifik feltyp finns kan GenericError användas eller specifika anpassade ClientErrors kan definieras.
Innan du börjar bearbeta återgivningen bör du kontrollera att alla parametrar är giltiga och stöds i den här arbetarens kontext:
- Kontrollera att återgivningsinstruktionsparametrarna för
SIZE,CONTRASTochBRIGHTNESSär giltiga. Om inte, utlöser du ett anpassat felRenditionInstructionsError.- En anpassad
RenditionInstructionsError-klass som utökarClientErrordefinieras längst ned i den här filen. Användning av ett specifikt, anpassat fel är användbart när test skrivs för arbetaren.
- En anpassad
'use strict';
const Jimp = require('jimp');
// Import the Asset Compute SDK provided `ClientError`
const { worker, SourceCorruptError, ClientError } = require('@adobe/asset-compute-sdk');
const fs = require('fs').promises;
exports.main = worker(async (source, rendition, params) => {
const stats = await fs.stat(source.path);
if (stats.size === 0) {
throw new SourceCorruptError('source file is empty');
}
// Read in parameters and set defaults if parameters are provided
const SIZE = parseInt(rendition.instructions.size) || 800;
const CONTRAST = parseFloat(rendition.instructions.contrast) || 0;
const BRIGHTNESS = parseFloat(rendition.instructions.brightness) || 0;
if (SIZE <= 10 || SIZE >= 10000) {
// Ensure size is within allowable bounds
throw new RenditionInstructionsError("'size' must be between 10 and 1,0000");
} else if (CONTRAST <= -1 || CONTRAST >= 1) {
// Ensure contrast is valid value
throw new RenditionInstructionsError("'contrast' must between -1 and 1");
} else if (BRIGHTNESS <= -1 || BRIGHTNESS >= 1) {
// Ensure contrast is valid value
throw new RenditionInstructionsError("'brightness' must between -1 and 1");
}
// Do work here
}
// Create a new ClientError to handle invalid rendition.instructions values
class RenditionInstructionsError extends ClientError {
constructor(message) {
// Provide a:
// + message: describing the nature of this erring condition
// + name: the name of the error; usually same as class name
// + reason: a short, searchable, unique error token that identifies this error
super(message, "RenditionInstructionsError", "rendition_instructions_error");
// Capture the strack trace
Error.captureStackTrace(this, RenditionInstructionsError);
}
}
Skapa återgivningen
När parametrarna har lästs, sanerats och validerats skrivs koden för att generera återgivningen. Pseudokoden för återgivningsgenereringen är följande:
-
Skapa en ny
renditionImage-arbetsyta i fyrkantiga dimensioner som anges med parameternsize. -
Skapa ett
image-objekt från källresursens binärfil -
Använd biblioteket Jimp för att omvandla bilden:
- Beskär originalbilden till en centrerad kvadrat
- Klipp ut en cirkel från mitten av bilden med fyrkant
- Anpassa till de dimensioner som definieras av parametervärdet
SIZE - Justera kontrast baserat på parametervärdet
CONTRAST - Justera intensiteten baserat på parametervärdet
BRIGHTNESS
-
Placera den omformade
imagemitt irenditionImagesom har en genomskinlig bakgrund -
Skriv det sammansatta,
renditionImagetillrendition.pathså att det kan sparas tillbaka till AEM som en resursåtergivning.
Den här koden använder Jimp API:er för att utföra dessa bildomformningar.
Asset Compute-arbetare måste slutföra sitt arbete synkront och rendition.path måste skrivas tillbaka helt till innan arbetarens renditionCallback slutförs. Detta kräver att asynkrona funktionsanrop görs synkrona med operatorn await. Om du inte känner till JavaScript asynkrona funktioner och hur de kan köras synkront, kan du bekanta dig med JavaScript-operatorn för väntan.
Den färdiga arbetaren index.js ska se ut så här:
'use strict';
const Jimp = require('jimp');
const { worker, SourceCorruptError, ClientError } = require('@adobe/asset-compute-sdk');
const fs = require('fs').promises;
exports.main = worker(async (source, rendition, params) => {
const stats = await fs.stat(source.path);
if (stats.size === 0) {
throw new SourceCorruptError('source file is empty');
}
// Read/parse and validate parameters
const SIZE = parseInt(rendition.instructions.size) || 800;
const CONTRAST = parseFloat(rendition.instructions.contrast) || 0;
const BRIGHTNESS = parseFloat(rendition.instructions.brightness) || 0;
if (SIZE <= 10 || SIZE >= 10000) {
throw new RenditionInstructionsError("'size' must be between 10 and 1,0000");
} else if (CONTRAST <= -1 || CONTRAST >= 1) {
throw new RenditionInstructionsError("'contrast' must between -1 and 1");
} else if (BRIGHTNESS <= -1 || BRIGHTNESS >= 1) {
throw new RenditionInstructionsError("'brightness' must between -1 and 1");
}
// Create target rendition image
let renditionImage = new Jimp(SIZE, SIZE, 0x0);
// Read and perform transformations on the source binary image
let image = await Jimp.read(source.path);
// Crop a circle from the source asset, and then apply contrast and brightness
image.crop(
image.bitmap.width < image.bitmap.height ? 0 : (image.bitmap.width - image.bitmap.height) / 2,
image.bitmap.width < image.bitmap.height ? (image.bitmap.height - image.bitmap.width) / 2 : 0,
image.bitmap.width < image.bitmap.height ? image.bitmap.width : image.bitmap.height,
image.bitmap.width < image.bitmap.height ? image.bitmap.width : image.bitmap.height
)
.circle()
.scaleToFit(SIZE, SIZE)
.contrast(CONTRAST)
.brightness(BRIGHTNESS);
// Place the transformed image onto the transparent renditionImage to save as PNG
renditionImage.composite(image, 0, 0)
// Write the final transformed image to the asset's rendition
await renditionImage.writeAsync(rendition.path);
});
// Custom error used for renditions.instructions parameter checking
class RenditionInstructionsError extends ClientError {
constructor(message) {
super(message, "RenditionInstructionsError", "rendition_instructions_error");
Error.captureStackTrace(this, RenditionInstructionsError);
}
}
Arbetaren körs
Nu när arbetskoden är klar och har registrerats och konfigurerats i manifest.yml kan den köras med det lokala Asset Compute Development Tool för att se resultatet.
-
Från Asset Compute-projektets rot
-
Kör
aio app run -
Vänta tills Asset Compute Development Tool öppnas i ett nytt fönster
-
I listrutan Välj en fil… väljer du en exempelbild som ska bearbetas
- Välj en exempelbildfil som ska användas som källresursens binärfil
- Om det inte finns någon ännu trycker du på (+) till vänster och överför en exempelbild -fil. Uppdatera webbläsarfönstret för utvecklingsverktyg
-
Uppdatera
"name": "rendition.png"som den här arbetaren för att skapa en genomskinlig PNG.- Observera att den här"name"-parametern bara används för utvecklingsverktyget och inte ska förlita sig på.
code language-json { "renditions": [ { "worker": "...", "name": "rendition.png" } ] } -
Tryck på Kör och vänta tills återgivningen genereras
-
Avsnittet Återgivningar förhandsvisar den återgivning som genererats. Tryck på renderingsförhandsvisningen för att hämta den fullständiga renderingen
Kör arbetaren med parametrar
Parametrar, som skickas via Bearbeta profilkonfigurationer, kan simuleras i Asset Compute Development Tools genom att tillhandahålla dem som nyckel/värde-par i återgivningsparametern JSON.
Funktionen
crop(width, height) för Jimp kräver till exempel att dess parametrar är int. Om parseInt(rendition.instructions.size) inte tolkas till ett int-värde misslyckas anropet till jimp.crop(SIZE, SIZE) eftersom parametrarna är inkompatibla med typen String.I vår kod accepteras parametrar för:
sizedefinierar återgivningens storlek (höjd och bredd som heltal)contrastdefinierar kontrastjusteringen, måste vara mellan -1 och 1, som flyttalbrightnessdefinierar den ljusa justeringen, måste vara mellan -1 och 1, som flyttal
Dessa läses i arbetaren index.js via:
const SIZE = parseInt(rendition.instructions.size) || 800const CONTRAST = parseFloat(rendition.instructions.contrast) || 0const BRIGHTNESS = parseFloat(rendition.instructions.brightness) || 0
-
Uppdatera återgivningsparametrarna för att anpassa storlek, kontrast och intensitet.
code language-json { "renditions": [ { "worker": "...", "name": "rendition.png", "size": "450", "contrast": "0.30", "brightness": "0.15" } ] } -
Tryck på Kör igen
-
Tryck på förhandsvisningen av återgivningen för att hämta och granska den genererade återgivningen. Observera dess dimensioner och hur kontrast och intensitet har ändrats jämfört med standardåtergivningen.
-
Överför andra bilder till listrutan Source-fil och försök köra arbetaren mot dem med andra parametrar!
Worker index.js on Github
Den sista index.js är tillgänglig på Github på: