@@ -8,9 +8,15 @@ import LocalDevelopment from "/snippets/local-development-extensions.mdx";
8
8
9
9
## Overview
10
10
11
- This task optimizes and watermarks an image using the Sharp library, and then uploads the processed image to R2 storage.
11
+ This task processes and watermarks an image using the Sharp library, and then uploads it to R2 storage.
12
12
13
- ## Adding build configurations
13
+ ## Prerequisites
14
+
15
+ - A project with [ Trigger.dev initialized] ( /quick-start )
16
+ - The [ Sharp] ( https://sharp.pixelplumbing.com/install ) library installed on your machine
17
+ - An R2-compatible object storage service, such as [ Cloudflare R2] ( https://developers.cloudflare.com/r2 )
18
+
19
+ ## Adding the build configuration
14
20
15
21
To use this example, you'll first need to add these build settings to your ` trigger.config.ts ` file:
16
22
@@ -34,22 +40,21 @@ export default defineConfig({
34
40
35
41
## Key features
36
42
37
- - Resizes and rotates an image
38
- - Adds a watermark to the image
39
- - Uploads the processed image to R2 storage
43
+ - Resizes a JPEG image to 800x800 pixels
44
+ - Adds a watermark to the image, positioned in the bottom-right corner, using a PNG image
45
+ - Uploads the processed image to R2 storage
40
46
41
47
## Task code
42
48
43
49
``` ts trigger/sharp-image-processing.ts
44
50
import { PutObjectCommand , S3Client } from " @aws-sdk/client-s3" ;
45
51
import { logger , task } from " @trigger.dev/sdk/v3" ;
46
52
import fs from " fs/promises" ;
47
- import fetch from " node-fetch" ;
48
53
import os from " os" ;
49
54
import path from " path" ;
50
55
import sharp from " sharp" ;
51
56
52
- // Initialize R2 client
57
+ // Initialize R2 client using your R2 account details
53
58
const r2Client = new S3Client ({
54
59
region: " auto" ,
55
60
endpoint: process .env .R2_ENDPOINT ,
@@ -61,6 +66,10 @@ const r2Client = new S3Client({
61
66
62
67
export const sharpProcessImage = task ({
63
68
id: " sharp-process-image" ,
69
+ // Only retry this task once if it fails
70
+ retry: {
71
+ maxAttempts: 1 ,
72
+ },
64
73
run : async (payload : { imageUrl: string ; watermarkUrl: string }) => {
65
74
const { imageUrl, watermarkUrl } = payload ;
66
75
@@ -76,10 +85,9 @@ export const sharpProcessImage = task({
76
85
const imageBuffer = await imageResponse .arrayBuffer ();
77
86
const watermarkBuffer = await watermarkResponse .arrayBuffer ();
78
87
79
- // Optimize the image using Sharp
88
+ // Process the image using Sharp
80
89
await sharp (Buffer .from (imageBuffer ))
81
- .rotate (90 ) // Rotate the image by 90 degrees
82
- .resize (800 , 600 ) // Resize the image to 800x600
90
+ .resize (800 , 800 ) // Resize the image to 800x800
83
91
.composite ([
84
92
{
85
93
input: Buffer .from (watermarkBuffer ),
@@ -89,34 +97,32 @@ export const sharpProcessImage = task({
89
97
.toFormat (" jpeg" )
90
98
.toFile (outputPath );
91
99
92
- // Log the output file path
93
- logger .log (` Optimized image saved at: ${outputPath } ` );
100
+ logger .log (` Image processed. ` );
94
101
95
- // Read the optimized image file
96
- const optimizedImageBuffer = await fs .readFile (outputPath );
102
+ // Read the processed image file
103
+ const processedImageBuffer = await fs .readFile (outputPath );
97
104
98
- // Upload the optimized image to R2, replacing slashes with underscores
105
+ // Upload the image to R2, replacing slashes with underscores
99
106
const r2Key = ` processed-images/${path .basename (outputPath )} ` ;
100
107
101
108
const uploadParams = {
102
109
Bucket: process .env .R2_BUCKET ,
103
110
Key: r2Key ,
104
- Body: optimizedImageBuffer ,
111
+ Body: processedImageBuffer ,
105
112
};
106
113
107
114
// Upload the image to R2 and get the URL
108
115
await r2Client .send (new PutObjectCommand (uploadParams ));
109
- const r2Url = ` https://${process .env .R2_ACCOUNT_ID }.r2.cloudflarestorage.com/${process .env .R2_BUCKET }/${r2Key } ` ;
110
- logger .log (" Optimized image uploaded to R2" , { url: r2Url });
116
+ logger .log (" Processed image uploaded to R2" , {
117
+ path: ` /${process .env .R2_BUCKET }/${r2Key } ` ,
118
+ });
111
119
112
120
// Delete the temporary file
113
121
await fs .unlink (outputPath );
122
+ logger .log (" Temporary file deleted" , { outputPath: outputPath });
114
123
115
- // Return the optimized image buffer, file path, and R2 URL
116
124
return {
117
- optimizedImageBuffer ,
118
- optimizedImagePath: outputPath ,
119
- r2Url ,
125
+ message: ` New image uploaded to /${process .env .R2_BUCKET }/${r2Key } ` ,
120
126
};
121
127
},
122
128
});
@@ -133,4 +139,4 @@ To test this task in the dashboard, you can use the following payload:
133
139
}
134
140
```
135
141
136
- <LocalDevelopment packages = { " the Sharp image processing library" } />
142
+ <LocalDevelopment packages = { " the Sharp image processing library" } />
0 commit comments