Skip to content

Commit 5c72f51

Browse files
committed
refactor: replace deprecated gm library with sharp in v2 sample
1 parent cf020ea commit 5c72f51

4 files changed

Lines changed: 27 additions & 36 deletions

File tree

functions/v2/imagemagick/index.js

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
// [START functions_imagemagick_setup]
1818
const functions = require('@google-cloud/functions-framework');
19-
const gm = require('gm').subClass({imageMagick: true});
19+
const sharp = require('sharp');
2020
const fs = require('fs').promises;
2121
const path = require('path');
2222
const vision = require('@google-cloud/vision');
@@ -64,6 +64,7 @@ functions.cloudEvent('blurOffensiveImages', async cloudEvent => {
6464
// Blurs the given file using ImageMagick, and uploads it to another bucket.
6565
const blurImage = async (file, blurredBucketName) => {
6666
const tempLocalPath = `/tmp/${path.parse(file.name).base}`;
67+
const tempLocalBlurredPath = `/tmp/blurred-${path.parse(file.name).base}`;
6768

6869
// Download file from bucket.
6970
try {
@@ -74,33 +75,31 @@ const blurImage = async (file, blurredBucketName) => {
7475
throw new Error(`File download failed: ${err}`);
7576
}
7677

77-
await new Promise((resolve, reject) => {
78-
gm(tempLocalPath)
79-
.blur(0, 16)
80-
.write(tempLocalPath, (err, stdout) => {
81-
if (err) {
82-
console.error('Failed to blur image.', err);
83-
reject(err);
84-
} else {
85-
console.log(`Blurred image: ${file.name}`);
86-
resolve(stdout);
87-
}
88-
});
89-
});
78+
try {
79+
await sharp(tempLocalPath).blur(16).toFile(tempLocalBlurredPath);
80+
81+
console.log(`Blurred image: ${file.name}`);
82+
} catch (err) {
83+
console.error('Failed to blur image.', err);
84+
throw err;
85+
}
9086

9187
// Upload result to a different bucket, to avoid re-triggering this function.
9288
const blurredBucket = storage.bucket(blurredBucketName);
9389

9490
// Upload the Blurred image back into the bucket.
9591
const gcsPath = `gs://${blurredBucketName}/${file.name}`;
9692
try {
97-
await blurredBucket.upload(tempLocalPath, {destination: file.name});
93+
await blurredBucket.upload(tempLocalBlurredPath, {destination: file.name});
9894
console.log(`Uploaded blurred image to: ${gcsPath}`);
9995
} catch (err) {
10096
throw new Error(`Unable to upload blurred image to ${gcsPath}: ${err}`);
97+
} finally {
98+
// Delete the temporary file.
99+
await Promise.allSettled([
100+
fs.unlink(tempLocalPath),
101+
fs.unlink(tempLocalBlurredPath),
102+
]);
101103
}
102-
103-
// Delete the temporary file.
104-
return fs.unlink(tempLocalPath);
105104
};
106105
// [END functions_imagemagick_blur]

functions/v2/imagemagick/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"@google-cloud/functions-framework": "^3.1.0",
1919
"@google-cloud/storage": "^7.0.0",
2020
"@google-cloud/vision": "^4.0.0",
21-
"gm": "^1.23.1"
21+
"sharp": "^0.34.5"
2222
},
2323
"devDependencies": {
2424
"c8": "^10.0.0",
@@ -27,4 +27,4 @@
2727
"sinon": "^18.0.0",
2828
"supertest": "^7.0.0"
2929
}
30-
}
30+
}

functions/v2/imagemagick/test/integration.test.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
'use strict';
1616

1717
const assert = require('assert');
18-
const {execSync} = require('child_process');
1918
const {Storage} = require('@google-cloud/storage');
2019
const sinon = require('sinon');
2120
const supertest = require('supertest');
@@ -34,11 +33,6 @@ const testFiles = {
3433

3534
require('../index');
3635

37-
// ImageMagick is available by default in Cloud Run Functions environments
38-
// https://cloud.google.com/functions/1stgendocs/tutorials/imagemagick-1st-gen.md#importing_dependencies
39-
// Manually install it for testing only.
40-
execSync('sudo apt-get install imagemagick -y');
41-
4236
describe('functions/imagemagick tests', () => {
4337
before(async () => {
4438
let exists;

functions/v2/imagemagick/test/unit.test.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,31 +38,29 @@ const loadSample = (adultResult, fileName) => {
3838
return {
3939
bucket: sinon.stub().returnsThis(),
4040
file: sinon.stub().returnsThis(),
41-
upload: sinon.stub().returnsThis(),
42-
download: sinon.stub().returnsThis(),
41+
upload: sinon.stub().resolves(),
42+
download: sinon.stub().resolves(),
4343
name: fileName,
4444
};
4545
},
4646
};
4747

48-
const gm = () => {
49-
return {
50-
blur: sinon.stub().returnsThis(),
51-
write: sinon.stub().yields(),
52-
};
48+
const sharpInstance = {
49+
blur: sinon.stub().returnsThis(),
50+
toFile: sinon.stub().resolves(),
5351
};
54-
gm.subClass = sinon.stub().returnsThis();
52+
const sharpMock = sinon.stub().returns(sharpInstance);
5553

5654
const fs = {
5755
promises: {
58-
unlink: sinon.stub(),
56+
unlink: sinon.stub().resolves(),
5957
},
6058
};
6159

6260
return proxyquire('..', {
6361
'@google-cloud/vision': vision,
6462
'@google-cloud/storage': storage,
65-
gm: gm,
63+
sharp: sharpMock,
6664
fs: fs,
6765
});
6866
};

0 commit comments

Comments
 (0)