在Firebase Cloud Functions中使用ImageMagick进行某些EPS转换时遇到问题。确实有效的方法每次都会起作用,而无效的方法总是失败,而且我也不明白为什么。
{ ChildProcessError: `convert -colorspace sRGB -density 300 input.eps -resize 400x400 output.png` failed with code 1
at ChildProcess.<anonymous> (/user_code/node_modules/child-process-promise/lib/index.js:132:23)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at maybeClose (internal/child_process.js:920:16)
at Socket.<anonymous> (internal/child_process.js:351:11)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at Pipe._handle.close [as _onclose] (net.js:509:12)
name: 'ChildProcessError',
code: 1,
childProcess:
ChildProcess {
domain: null,
_events: { error: [Function: t], close: [Function] },
_eventsCount: 2,
_maxListeners: undefined,
_closesNeeded: 3,
_closesGot: 3,
connected: false,
signalCode: null,
exitCode: 1,
killed: false,
spawnfile: 'convert',
_handle: null,
spawnargs:
[ 'convert',
'-colorspace',
'sRGB',
'-density',
'300',
'input.eps',
'-resize',
'400x400',
'output.png' ],
pid: 12,
stdin:
Socket {
connecting: false,
_hadError: false,
_handle: null,
_parent: null,
_host: null,
_readableState: [Object],
readable: false,
domain: null,
_events: [Object],
_eventsCount: 2,
_maxListeners: undefined,
_writableState: [Object],
writable: false,
allowHalfOpen: false,
destroyed: true,
_bytesDispatched: 0,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
write: [Function: writeAfterFIN],
_idleNext: null,
_idlePrev: null,
_idleTimeout: -1 },
stdout:
Socket {
connecting: false,
_hadError: false,
_handle: null,
_parent: null,
_host: null,
_readableState: [Object],
readable: false,
domain: null,
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
_writableState: [Object],
writable: false,
allowHalfOpen: false,
destroyed: true,
_bytesDispatched: 0,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
_idleNext: null,
_idlePrev: null,
_idleTimeout: -1,
write: [Function: writeAfterFIN] },
stderr:
Socket {
connecting: false,
_hadError: false,
_handle: null,
_parent: null,
_host: null,
_readableState: [Object],
readable: false,
domain: null,
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
_writableState: [Object],
writable: false,
allowHalfOpen: false,
destroyed: true,
_bytesDispatched: 0,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
write: [Function: writeAfterFIN],
read: [Function],
_consuming: true,
_idleNext: null,
_idlePrev: null,
_idleTimeout: -1 },
stdio: [ [Object], [Object], [Object] ] },
stdout: undefined,
stderr: undefined }
/**
* When an image is uploaded in the Storage bucket We generate a thumbnail automatically using
* ImageMagick.
* After the thumbnail has been generated and uploaded to Cloud Storage,
* we write the public URL to Firestore.
*/
exports.generateThumbnail = functions.storage.object().onFinalize((object) => {
// File and directory paths.
const filePath = object.name;
const contentType = object.contentType; // This is the image MIME type
const fileDir = path.dirname(filePath);
const fileName = path.basename(filePath);
const thumbFilePath = path.normalize(path.join(fileDir, `${THUMB_PREFIX}${fileName}.png`));
const tempLocalFile = path.join(os.tmpdir(), filePath);
const tempLocalDir = path.dirname(tempLocalFile);
const tempLocalThumbFile = path.join(os.tmpdir(), thumbFilePath);
// Don't run when deleting files
if (object.resourceState === 'not_exists') {
console.log('Deleted file');
return null;
}
// Check if it's a eps, ps or ai file before proceeding
if (contentType != "application/postscript") {
console.log("We don't need to transform this file");
return null;
}
// Exit if the image is already a thumbnail.
if (fileName.startsWith(THUMB_PREFIX)) {
console.log('Already a Thumbnail.');
return null;
}
// Cloud Storage files.
const bucket = gcs.bucket(object.bucket);
const file = bucket.file(filePath);
const thumbFile = bucket.file(thumbFilePath);
const metadata = {
contentType: 'image/png',
// To enable Client-side caching you can set the Cache-Control headers here. Uncomment below.
// 'Cache-Control': 'public,max-age=3600',
};
// Create the temp directory where the storage file will be downloaded.
return mkdirp(tempLocalDir).then(() => {
// Download file from bucket.
return file.download({ destination: tempLocalFile });
}).then(() => {
console.log("The file has been downloaded to", tempLocalFile);
// Generate a thumbnail using ImageMagick.
return spawn('convert', ['-colorspace', 'sRGB', '-density', '300', tempLocalFile, '-resize', '400x400', tempLocalThumbFile]);
}).then(() => {
console.log('Thumbnail created at', tempLocalThumbFile);
// Uploading the Thumbnail.
return bucket.upload(tempLocalThumbFile, { destination: thumbFilePath, metadata: metadata });
}).then(() => {
console.log('Thumbnail uploaded to Storage at', thumbFilePath);
// Once the image has been uploaded delete the local files to free up disk space.
fs.unlinkSync(tempLocalFile);
fs.unlinkSync(tempLocalThumbFile);
// Get the Signed URLs for the thumbnail and original image.
const config = {
action: 'read',
expires: '03-01-2500',
};
return Promise.all([
thumbFile.getSignedUrl(config)
]);
}).then((results) => {
const thumbResult = results[0];
const thumbFileUrl = thumbResult[0];
console.log('Got Signed URLs: ' + results);
console.log('Thumb result:' + thumbResult);
console.log('Thumb file URL: ' + thumbFileUrl);
// Add the URLs to the Database
return admin.firestore().doc(fileDir).update({ thumb_src: thumbFileUrl, processed: true }).then(() => {
// write is complete here
console.log("Thumbnail URLs saved to database.");
});
}).catch((error) => {
console.error(error);
});
});
让我知道是否需要提供更多信息,但是就像我说的那样-该代码适用于某些EPS文件。首先,我认为问题可能出在输入文件的文件大小上,并且转换没有等待下载完成-但是我不确定是否是这种情况。