Google Cloud Functions image processing 图像处理需要几分钟
Google Cloud Functions image processing takes minutes for image processing
我正在使用云功能做什么:
- 正在将 url 下载到
/tmp
目录。
- 运行 转换为创建最大尺寸 (600*600) 的缩略图。
- 将其存储在 Firebase 存储中。
- 正在写回 Firebase 实时数据库。
整个操作需要将近 2-3 分钟,如果我并行执行 5-6 个函数,则只有 1-2 个完成。
这是代码。请让我知道在这方面可以做什么:
'use strict';
const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();
//const exec = require('child-process-promise').exec;
const image_downloader = require('image-downloader');
const spawn = require('child-process-promise').spawn;
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const LOCAL_TMP_FOLDER = '/tmp/';
// File extension for the created JPEG files.
const JPEG_EXTENSION = 'jpg';
const MAX_HEIGHT = 600;
const MAX_WIDTH = 600;
const bucket_name='-----------';
//const THUMB_SUFFIX = '_thumb';
exports.moderator = functions.database
.ref('/users/{user_id}/photo_processing/{photo_processing_id}').onWrite(event => {
const photo_data = event.data.val();
if(!photo_data){
return;
}
const user_id=event.params.user_id;
const fileName=`${event.params.photo_processing_id}.jpg`;
const fileLocation=`/tmp/${fileName}`;
const modifiedfileName=`${event.params.user_id}_${fileName}`;
const modifiedfileLocation=`/tmp/${modifiedfileName}`;
console.log("fileName fileLocation modifiedfileName modifiedfileLocation",fileName,fileLocation,modifiedfileName,modifiedfileLocation);
const options = {
url: photo_data.source,
dest: fileLocation, // Save to /path/to/dest/image.jpg
done: function(err, filename, image) {
if (err) {
console.log('error occured', err);
}
console.log('File saved to', filename);
// Uploading the JPEG image.
const bucket = gcs.bucket(bucket_name);
const destinationUrl=`photos/${modifiedfileName}`;
return spawn('convert', [fileLocation, '-thumbnail', `${MAX_WIDTH}x${MAX_HEIGHT}>`, modifiedfileLocation]).then(() => {
console.log('Thumbnail created at', modifiedfileLocation);
return bucket.upload(modifiedfileLocation, {
destination: destinationUrl
}).then(() => {
console.log('JPEG image uploaded to Storage at',modifiedfileName );
return admin.database().ref(`/users/${user_id}/photos`).push(destinationUrl);
});
})
}
}
image_downloader(options);
});
我能够解决 this.Problem 是云函数应该 return 一个承诺,否则它们会表现得很奇怪。
这是可行的解决方案:
'use strict';
const functions = require('firebase-functions');
//const mkdirp = require('mkdirp-promise');
const gcs = require('@google-cloud/storage')();
//const exec = require('child-process-promise').exec;
const image_downloader = require('image-downloader');
const spawn = require('child-process-promise').spawn;
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const LOCAL_TMP_FOLDER = '/tmp/';
// File extension for the created JPEG files.
const JPEG_EXTENSION = 'jpg';
const MAX_HEIGHT = 600;
const MAX_WIDTH = 600;
const bucket_name='--------';
//const THUMB_SUFFIX = '_thumb';
const fetch=(source,filename,fileLocation)=> new Promise((resolve,reject)=>{
console.log("details passed to fetch method",source,filename,fileLocation);
const options = {
url: source,
dest: fileLocation, // Save to /path/to/dest/image.jpg
done: function(err, filename, image) {
if (err) {
reject(err);
console.log('error occured', err);
}
resolve(filename);
console.log('File saved to', filename);
}
}
image_downloader(options);
});
exports.moderator = functions.database
.ref('/users/{user_id}/photo_processing/{photo_processing_id}').onWrite(event => {
const photo_data = event.data.val();
if(!photo_data){
return;
}
const user_id=event.params.user_id;
//console.log("photo data came to the firebase funciotn",photo_data);
//console.log('user_id passed', event.params.user_id);
//console.log('photo_processing_id passed', event.params.photo_processing_id);
const fileName=`${event.params.photo_processing_id}.jpg`;
const fileLocation=`/tmp/${fileName}`;
const modifiedfileName=`${event.params.user_id}_${fileName}`;
const modifiedfileLocation=`/tmp/${modifiedfileName}`;
const is_profile=photo_data.is_profile;
const created_time=photo_data.created_time;
console.log("fileName fileLocation modifiedfileName modifiedfileLocation",fileName,fileLocation,modifiedfileName,modifiedfileLocation);
const bucket = gcs.bucket(bucket_name);
const destinationUrl=`photos/${modifiedfileName}`;
return fetch(photo_data.source,fileName,fileLocation).then(()=>
{
return spawn('convert', [fileLocation, '-thumbnail', `${MAX_WIDTH}x${MAX_HEIGHT}>`, modifiedfileLocation]).then(() =>
{
console.log('Thumbnail created at', modifiedfileLocation);
return bucket.upload(modifiedfileLocation, {
destination: destinationUrl
}).then(() => {
console.log('JPEG image uploaded to Storage at',modifiedfileName );
const photo_data_to_save={url:destinationUrl,created_time};
if(is_profile){
photo_data_to_save.is_profile=true;
}
admin.database().ref(`/users/${user_id}/userData/photos`).push(photo_data_to_save);
return null;
})
});
})
});
我正在使用云功能做什么:
- 正在将 url 下载到
/tmp
目录。 - 运行 转换为创建最大尺寸 (600*600) 的缩略图。
- 将其存储在 Firebase 存储中。
- 正在写回 Firebase 实时数据库。
整个操作需要将近 2-3 分钟,如果我并行执行 5-6 个函数,则只有 1-2 个完成。 这是代码。请让我知道在这方面可以做什么:
'use strict';
const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();
//const exec = require('child-process-promise').exec;
const image_downloader = require('image-downloader');
const spawn = require('child-process-promise').spawn;
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const LOCAL_TMP_FOLDER = '/tmp/';
// File extension for the created JPEG files.
const JPEG_EXTENSION = 'jpg';
const MAX_HEIGHT = 600;
const MAX_WIDTH = 600;
const bucket_name='-----------';
//const THUMB_SUFFIX = '_thumb';
exports.moderator = functions.database
.ref('/users/{user_id}/photo_processing/{photo_processing_id}').onWrite(event => {
const photo_data = event.data.val();
if(!photo_data){
return;
}
const user_id=event.params.user_id;
const fileName=`${event.params.photo_processing_id}.jpg`;
const fileLocation=`/tmp/${fileName}`;
const modifiedfileName=`${event.params.user_id}_${fileName}`;
const modifiedfileLocation=`/tmp/${modifiedfileName}`;
console.log("fileName fileLocation modifiedfileName modifiedfileLocation",fileName,fileLocation,modifiedfileName,modifiedfileLocation);
const options = {
url: photo_data.source,
dest: fileLocation, // Save to /path/to/dest/image.jpg
done: function(err, filename, image) {
if (err) {
console.log('error occured', err);
}
console.log('File saved to', filename);
// Uploading the JPEG image.
const bucket = gcs.bucket(bucket_name);
const destinationUrl=`photos/${modifiedfileName}`;
return spawn('convert', [fileLocation, '-thumbnail', `${MAX_WIDTH}x${MAX_HEIGHT}>`, modifiedfileLocation]).then(() => {
console.log('Thumbnail created at', modifiedfileLocation);
return bucket.upload(modifiedfileLocation, {
destination: destinationUrl
}).then(() => {
console.log('JPEG image uploaded to Storage at',modifiedfileName );
return admin.database().ref(`/users/${user_id}/photos`).push(destinationUrl);
});
})
}
}
image_downloader(options);
});
我能够解决 this.Problem 是云函数应该 return 一个承诺,否则它们会表现得很奇怪。
这是可行的解决方案:
'use strict';
const functions = require('firebase-functions');
//const mkdirp = require('mkdirp-promise');
const gcs = require('@google-cloud/storage')();
//const exec = require('child-process-promise').exec;
const image_downloader = require('image-downloader');
const spawn = require('child-process-promise').spawn;
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const LOCAL_TMP_FOLDER = '/tmp/';
// File extension for the created JPEG files.
const JPEG_EXTENSION = 'jpg';
const MAX_HEIGHT = 600;
const MAX_WIDTH = 600;
const bucket_name='--------';
//const THUMB_SUFFIX = '_thumb';
const fetch=(source,filename,fileLocation)=> new Promise((resolve,reject)=>{
console.log("details passed to fetch method",source,filename,fileLocation);
const options = {
url: source,
dest: fileLocation, // Save to /path/to/dest/image.jpg
done: function(err, filename, image) {
if (err) {
reject(err);
console.log('error occured', err);
}
resolve(filename);
console.log('File saved to', filename);
}
}
image_downloader(options);
});
exports.moderator = functions.database
.ref('/users/{user_id}/photo_processing/{photo_processing_id}').onWrite(event => {
const photo_data = event.data.val();
if(!photo_data){
return;
}
const user_id=event.params.user_id;
//console.log("photo data came to the firebase funciotn",photo_data);
//console.log('user_id passed', event.params.user_id);
//console.log('photo_processing_id passed', event.params.photo_processing_id);
const fileName=`${event.params.photo_processing_id}.jpg`;
const fileLocation=`/tmp/${fileName}`;
const modifiedfileName=`${event.params.user_id}_${fileName}`;
const modifiedfileLocation=`/tmp/${modifiedfileName}`;
const is_profile=photo_data.is_profile;
const created_time=photo_data.created_time;
console.log("fileName fileLocation modifiedfileName modifiedfileLocation",fileName,fileLocation,modifiedfileName,modifiedfileLocation);
const bucket = gcs.bucket(bucket_name);
const destinationUrl=`photos/${modifiedfileName}`;
return fetch(photo_data.source,fileName,fileLocation).then(()=>
{
return spawn('convert', [fileLocation, '-thumbnail', `${MAX_WIDTH}x${MAX_HEIGHT}>`, modifiedfileLocation]).then(() =>
{
console.log('Thumbnail created at', modifiedfileLocation);
return bucket.upload(modifiedfileLocation, {
destination: destinationUrl
}).then(() => {
console.log('JPEG image uploaded to Storage at',modifiedfileName );
const photo_data_to_save={url:destinationUrl,created_time};
if(is_profile){
photo_data_to_save.is_profile=true;
}
admin.database().ref(`/users/${user_id}/userData/photos`).push(photo_data_to_save);
return null;
})
});
})
});