Цель моего кода 1) Пользователь отправит URL-адрес изображения 2) Бот читает URL 3) Бот сохраняет изображение в папку "images" 4) Бот конвертирует изображение в тензор с помощью tfjs 5) Бот использует COCO-SSD JS в качестве предварительно обученной модели (с тензором изображения в качестве параметра) и печатает, а затем отправляет результат.
Теперь моя проблема в том, что всякий раз, когда я пытаюсь сохранить изображения, используя их URL-адрес, я получаю файл, который не может прочитать ни программа, ни окна!
Это сработало один раз, имея возможность открывать и использовать файлы . Но теперь возвращает файлы, которые Windows 10 не может читать в формате .PNG или .JPG.
Вот мой код:
const {Client, MessageAttachment} = require('discord.js');
const bot = new Client();
const tf = require('@tensorflow/tfjs-node');
const ts = require('@tensorflow/tfjs-core');
require('@tensorflow/tfjs-backend-cpu');
require('@tensorflow/tfjs-backend-webgl');
const coco = require('@tensorflow-models/coco-ssd');
const fs = require('fs');
const fetch = require("node-fetch");
const https = require('https');
const request = require('request');
bot.on('message', gotMessage);
function gotMessage(msg) {
if (msg.content === '!object') {
const attachments = (msg.attachments).array();
const filepath = "./images/" + Date.now() + "J" + ".jpg";
console.info(filepath);
const imageurl = attachments[0].url;
saveImageToDisk(imageurl,filepath)
const img_buffer = fs.readFileSync(filepath)
const img = tf.node.decodeImage(img_buffer)
coco.load().then(model => {
// detect objects in the image.
model.detect(img).then(predictions => {
console.info('Predictions: ', predictions);
});
});
msg.reply('Enjoy');
msg.channel.send(attachments[0].url);
}
}
function saveImageToDisk(url,path) {
var fullUrl = url;
var localPath = fs.createWriteStream(path);
var request = https.get(fullUrl,function(response) {
console.info(response)
response.pipe(localPath)
});
}
P.S. Буква "J" после Date.now()
предназначена.
Я ДЕЙСТВИТЕЛЬНО не уверен, что он сохраняет как. Но учебные пособия предполагают, что простое добавление «.PNG» в конце может превратить его в PNG. (Возможно, мне следует начать с этого, спасибо!)
Я вижу, что ваше приложение полностью не синхронизировано - что я имею в виду
у вас есть saveImageToDisk(imageurl,filepath)
который будет записывать файл на диск, но он выполняется, ставит файл на запись в очередь, и вы читаете (еще не сохраненный) файл с синхронизацией.
Я попытаюсь немного исправить это, чтобы вы показали хотя бы один способ сделать это, но вам нужно подумать о некоторой синхронизации в вашем коде, когда вы планируете поток приложения.
console.info('Authenticating bot...');
const {Client, MessageAttachment} = require('discord.js');
const bot = new Client();
const tf = require('@tensorflow/tfjs-node');
const ts = require('@tensorflow/tfjs-core');
require('@tensorflow/tfjs-backend-cpu');
require('@tensorflow/tfjs-backend-webgl');
const coco = require('@tensorflow-models/coco-ssd');
const fs = require('fs');
const fetch = require("node-fetch");
const https = require('https');
const request = require('request');
bot.login('BOTTOKEN');
bot.on('ready', readyDiscord);
function readyDiscord() {
console.info('Authenticated and On!');
}
bot.on('message', gotMessage);
async function gotMessage(msg) {
if (msg.content === '!object') {
const attachments = (msg.attachments).array();
const filepath = "./images/" + Date.now() + "J" + ".jpg";
console.info(filepath);
const imageurl = attachments[0].url;
await saveImageToDisk(imageurl,filepath)
const img_buffer = fs.readFileSync(filepath)
const img = tf.node.decodeImage(img_buffer)
coco.load().then(model => {
// detect objects in the image.
model.detect(img).then(predictions => {
console.info('Predictions: ', predictions);
});
});
msg.reply('Enjoy');
msg.channel.send(attachments[0].url);
}
}
async function saveImageToDisk(url,path) {
return new Promise((resolve, reject) => {
var fullUrl = url;
var localPath = fs.createWriteStream(path);
var request = https.get(fullUrl,function(response) {
console.info(response)
response.pipe(localPath)
response.on('end', resolve);
}).on('error', reject);
});
}
Таким образом, перед выполнением кода, который читает еще не заполненные файлы, код "подождет", пока файл не будет записан (или не произойдет ошибка) - вы, конечно, должны попытаться отловить ошибки и разобраться с ними.
Итак, созданный объект имеет тип «файл»? Есть ли вообще расширение в имени файла? Мне любопытно, что возвращается, действительно файл изображения?