我正在从网址中读取图像并对其进行处理。我需要将此数据上传到云存储中的文件,目前我正在将数据写入文件并上传此文件然后删除此文件。有没有办法可以将数据直接上传到云存储?
static async uploadDataToCloudStorage(rc : RunContextServer, bucket : string, path : string, data : any, mimeVal : string | false) : Promise<string> {
if(!mimeVal) return ''
const extension = mime.extension(mimeVal),
filename = await this.getFileName(rc, bucket, extension, path),
modPath = (path) ? (path + '/') : '',
res = await fs.writeFileSync(`/tmp/${filename}.${extension}`, data, 'binary'),
fileUrl = await this.upload(rc, bucket,
`/tmp/${filename}.${extension}`,
`${modPath}${filename}.${extension}`)
await fs.unlinkSync(`/tmp/${filename}.${extension}`)
return fileUrl
}
static async upload(rc : RunContextServer, bucketName: string, filePath : string, destination : string) : Promise<string> {
const bucket : any = cloudStorage.bucket(bucketName),
data : any = await bucket.upload(filePath, {destination})
return data[0].metadata.name
}
答案 0 :(得分:5)
是的,可以使用nodejs从URL检索图像,对图像进行编辑并将其上传到Google Cloud Storage(或Firebase存储),而无需在本地保存文件。
这是基于Akash的答案的,它对我有用,包括图像处理步骤在内的整个功能。
如果您是使用Firebase存储的 firebase 用户,则仍必须使用此库。用于存储的Firebase Web实施在节点中不起作用。如果您是在firebase中创建存储的,则仍然可以通过Google Cloud Storage Console进行全部访问。他们是同一回事。
const axios = require('axios');
const sharp = require('sharp');
const { Storage } = require('@google-cloud/storage');
const processImage = (imageUrl) => {
return new Promise((resolve, reject) => {
// Your Google Cloud Platform project ID
const projectId = '<project-id>';
// Creates a client
const storage = new Storage({
projectId: projectId,
});
// Configure axios to receive a response type of stream, and get a readableStream of the image from the specified URL
axios({
method:'get',
url: imageUrl,
responseType:'stream'
})
.then((response) => {
// Create the image manipulation function
var transformer = sharp()
.resize(300)
.jpeg();
gcFile = storage.bucket('<bucket-path>').file('my-file.jpg')
// Pipe the axios response data through the image transformer and to Google Cloud
response.data
.pipe(transformer)
.pipe(gcFile.createWriteStream({
resumable : false,
validation : false,
contentType: "auto",
metadata : {
'Cache-Control': 'public, max-age=31536000'}
}))
.on('error', (error) => {
reject(error)
})
.on('finish', () => {
resolve(true)
});
})
.catch(err => {
reject("Image transfer error. ", err);
});
})
}
processImage("<url-to-image>")
.then(res => {
console.log("Complete.", res);
})
.catch(err => {
console.log("Error", err);
});
答案 1 :(得分:4)
可以使用节点流上传数据而无需写入文件。
git version 2.10.2.windows.1
答案 2 :(得分:0)
您还可以上传多个文件:
@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles())
const storage = new Storage();
for (const file of files) {
const dataStream = new stream.PassThrough();
const gcFile = storage.bucket('upload-lists').file(file.originalname)
dataStream.push(file.buffer);
dataStream.push(null);
new Promise((resolve, reject) => {
dataStream.pipe(gcFile.createWriteStream({
resumable: false,
validation: false,
// Enable long-lived HTTP caching headers
// Use only if the contents of the file will never change
// (If the contents will change, use cacheControl: 'no-cache')
metadata: { 'Cache-Control': 'public, max-age=31536000' }
})).on('error', (error: Error) => {
reject(error)
}).on('finish', () => {
resolve(true)
})
})
}
答案 3 :(得分:0)
这个线程是旧的,但在当前的 API 中,File
对象适用于 Streams
所以你可以用这样的东西从内存上传一个 JSON 文件:
const { Readable } = require("stream")
const { Storage } = require('@google-cloud/storage');
const bucketName = '...';
const filePath = 'test_file_from_memory.json';
const storage = new Storage({
projectId: '...',
keyFilename: '...'
});
(() => {
const json = {
prop: 'one',
att: 2
};
const file = storage.bucket(bucketName).file(filePath);
Readable.from(JSON.stringify(json))
.pipe(file.createWriteStream({
metadata: {
contentType: 'text/json'
}
}).on('error', (error) => {
console.log('error', error)
}).on('finish', () => {
console.log('done');
}));
})();