在 Firebase/Angular 应用中使用 sharp API 后 MIME 类型错误
Wrong MIME type after using sharp API with Firebase/Angular app
我正在调用 sharp(tmpFilePath).resize(150, 150).toFile(resizedFilePath)
(使用尖锐的 api: http://sharp.pixelplumbing.com/en/v0.15.1/api/)但是正在生成的输出文件显示为类型 application/octet-stream
而不是 image/jpeg
,这是原始文件类型。我正在通过云功能使用 Angular 和 downloading/uploading 到 Firebase 存储。当我下载源文件并将其上传回 Firebase 而没有先调用 sharp API 时,新上传的文件是预期的 image/jpeg
文件。
我最初是按照本教程学习的 (https://angularfirebase.com/lessons/image-thumbnail-resizer-cloud-function/),但实际上我无法使用他的方法或 Firebase 文档上的方法访问我的存储桶:const gcs = require('@google-cloud/storage')();
但我能够访问它通过管理员 const bucket = admin.storage().bucket(object.bucket);
。我不得不使用这个变通办法似乎很可疑,但同样,如果我省略 sharp
api 调用,我的函数运行良好......所以我只是不知道它是根我的问题的原因?
我在 github (https://github.com/lovell/sharp/issues/1493) 上提交了这个问题,但所有者似乎认为这个问题与 sharp
无关。知道我在这里做错了什么吗?或者至少有人可以帮助我缩小问题范围,以便我可以尝试更好的 google 搜索吗?
原文件:
Sharp 返回的文件 API:
我的函数来自 index.ts:
import * as functions from 'firebase-functions';
import { tmpdir } from 'os';
import { join, dirname } from 'path';
import * as sharp from 'sharp';
import * as fs from 'fs-extra';
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
export const resizeImages = functions.storage.object().onFinalize(async object => {
try {
console.log(object);
const bucket = admin.storage().bucket(object.bucket);
const filePath = object.name;
const fileName:string = filePath.split('/').pop();
const bucketDir = dirname(filePath);
console.log("filePath: " + filePath + "; fileName: " + fileName + "; bucketDir: " + bucketDir);
if (bucketDir === 'profile-image' && object.contentType.includes('image')){
console.log("A profile picture was added...")
//The file is a profile picture...
if (fileName.includes('unsized@')) {
console.log("The picture that was added hasn't been sized yet...")
//The file needs to be resized...
const workingDir = join(tmpdir(), 'thumbs');
const tmpFilePath = join(workingDir, fileName);
// 1. Ensure thumbnail dir exists
await fs.ensureDir(workingDir);
// 2. Download Source File
await bucket.file(filePath).download({
destination: tmpFilePath
});
console.log("Downloaded the source file");
console.log(tmpFilePath);
// 3. Resize the image ********THIS PART IS NOT HAPPENING CORRECTLY
console.log("About to start resizing...");
const resizedfileName: string = fileName.split('@').pop();
const resizedFilePath = join(workingDir, resizedfileName);
await sharp(tmpFilePath).resize(150, 150).toFile(resizedFilePath);
console.log("The image resizing is complete: "+ resizedFilePath);
// 4. Upload the resized image
const resizedImageUploadSnapshot = await bucket.upload(resizedFilePath, {destination: join('profile-image', resizedfileName)});
console.log("Uploaded the resized image ");
// 5. Cleanup remove the tmp/thumbs from the filesystem
await fs.remove(workingDir);
console.log("FUNCTION COMPLETED SUCCESSFULLY!")
return true;
} else {
return false;
}
} else {
console.log('exiting function');
return false;
}
} catch (error) {
console.log(error);
return error;
}
我的 package.json 函数文件夹中的文件:
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"main": "lib/index.js",
"dependencies": {
"@google-cloud/storage": "^2.3.1",
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.1.0",
"firebase-tools": "^6.1.1",
"fs-extra": "^7.0.1",
"sharp": "^0.21.0",
"stripe": "^6.15.1"
},
"devDependencies": {
"tslint": "~5.8.0",
"typescript": "^3.2.1"
},
"private": true
}
我通过在路径中添加文件扩展名解决了这个问题,如下所示:
const tmpFilePath = join(workingDir, fileName + '.jpeg');
和
const resizedFilePath = join(workingDir, resizedfileName + '.jpeg');
我正在调用 sharp(tmpFilePath).resize(150, 150).toFile(resizedFilePath)
(使用尖锐的 api: http://sharp.pixelplumbing.com/en/v0.15.1/api/)但是正在生成的输出文件显示为类型 application/octet-stream
而不是 image/jpeg
,这是原始文件类型。我正在通过云功能使用 Angular 和 downloading/uploading 到 Firebase 存储。当我下载源文件并将其上传回 Firebase 而没有先调用 sharp API 时,新上传的文件是预期的 image/jpeg
文件。
我最初是按照本教程学习的 (https://angularfirebase.com/lessons/image-thumbnail-resizer-cloud-function/),但实际上我无法使用他的方法或 Firebase 文档上的方法访问我的存储桶:const gcs = require('@google-cloud/storage')();
但我能够访问它通过管理员 const bucket = admin.storage().bucket(object.bucket);
。我不得不使用这个变通办法似乎很可疑,但同样,如果我省略 sharp
api 调用,我的函数运行良好......所以我只是不知道它是根我的问题的原因?
我在 github (https://github.com/lovell/sharp/issues/1493) 上提交了这个问题,但所有者似乎认为这个问题与 sharp
无关。知道我在这里做错了什么吗?或者至少有人可以帮助我缩小问题范围,以便我可以尝试更好的 google 搜索吗?
原文件:
Sharp 返回的文件 API:
我的函数来自 index.ts:
import * as functions from 'firebase-functions';
import { tmpdir } from 'os';
import { join, dirname } from 'path';
import * as sharp from 'sharp';
import * as fs from 'fs-extra';
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
export const resizeImages = functions.storage.object().onFinalize(async object => {
try {
console.log(object);
const bucket = admin.storage().bucket(object.bucket);
const filePath = object.name;
const fileName:string = filePath.split('/').pop();
const bucketDir = dirname(filePath);
console.log("filePath: " + filePath + "; fileName: " + fileName + "; bucketDir: " + bucketDir);
if (bucketDir === 'profile-image' && object.contentType.includes('image')){
console.log("A profile picture was added...")
//The file is a profile picture...
if (fileName.includes('unsized@')) {
console.log("The picture that was added hasn't been sized yet...")
//The file needs to be resized...
const workingDir = join(tmpdir(), 'thumbs');
const tmpFilePath = join(workingDir, fileName);
// 1. Ensure thumbnail dir exists
await fs.ensureDir(workingDir);
// 2. Download Source File
await bucket.file(filePath).download({
destination: tmpFilePath
});
console.log("Downloaded the source file");
console.log(tmpFilePath);
// 3. Resize the image ********THIS PART IS NOT HAPPENING CORRECTLY
console.log("About to start resizing...");
const resizedfileName: string = fileName.split('@').pop();
const resizedFilePath = join(workingDir, resizedfileName);
await sharp(tmpFilePath).resize(150, 150).toFile(resizedFilePath);
console.log("The image resizing is complete: "+ resizedFilePath);
// 4. Upload the resized image
const resizedImageUploadSnapshot = await bucket.upload(resizedFilePath, {destination: join('profile-image', resizedfileName)});
console.log("Uploaded the resized image ");
// 5. Cleanup remove the tmp/thumbs from the filesystem
await fs.remove(workingDir);
console.log("FUNCTION COMPLETED SUCCESSFULLY!")
return true;
} else {
return false;
}
} else {
console.log('exiting function');
return false;
}
} catch (error) {
console.log(error);
return error;
}
我的 package.json 函数文件夹中的文件:
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"main": "lib/index.js",
"dependencies": {
"@google-cloud/storage": "^2.3.1",
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.1.0",
"firebase-tools": "^6.1.1",
"fs-extra": "^7.0.1",
"sharp": "^0.21.0",
"stripe": "^6.15.1"
},
"devDependencies": {
"tslint": "~5.8.0",
"typescript": "^3.2.1"
},
"private": true
}
我通过在路径中添加文件扩展名解决了这个问题,如下所示:
const tmpFilePath = join(workingDir, fileName + '.jpeg');
和
const resizedFilePath = join(workingDir, resizedfileName + '.jpeg');