I am trying to upload files directly to Cloudinary using nodejs. I have gotten in to work successfully, but ONLY when I manually set the path of the image I am going to be upload, like so:
cloudinary.uploader.upload('./public/css/img/' + data.image)
but when I do this:
cloudinary.uploader.upload(data.image)
it does not work. A sample of my entire function is below. I need it to work like this because when I allow others (not on my local machine) to upload images, it will not work.
// collected image from a user
const data = {
image: req.query.image,
}
console.log(data)
// upload image here
cloudinary.uploader.upload(data.image)
.then((result) => {
// response.status(200).send({
// message: "success",
// result,
// });
console.log(result.secure_url)
When running the upload call from the root folder it searches for the image in the same folder. You can run the upload from the img folder. e.g cd ./public/css/img/ and then call the upload. or use the full path as you did.
Related
I want to display images that users upload to storage/uploads/ folder which is outside of the website's root folder (Because I don't want other users to have access to each other's uploaded photos).
I did a test and tried to use the File Response as described in the docs: https://laravel.com/docs/9.x/responses#file-responses
This is how I did it:
In web.php:
Route::get('show_image', [ImageController::class, 'show_image']);
In ImageController:
public function show_image(Request $request)
{
$pathToFile = '../storage/uploads/460s6DLmCnvoom90S7wfk.jpg';
return response()->file($pathToFile);
}
Now when I enter the url of the route in the browser: http://mysite.dev/show_image it displays me the image in the browser inside an img tag with src=http://mysite.dev/show_image (Not a blade file or anything, I simply enter the URL in the browser and it does that automatically.
But the above example was done only with 1 file, and with simply going to the URL in the browser.
But what I really need is to fetch many images from the storage/uploads/ folder using AJAX (Or Fetch API in my case) and then append these images to a list in the browser.
Currently this is how I fetch the files with Fetch API:
const getImagesPromise = fetch('get_images');
getImages
.then((response) => {
})
.then((data) => {
});
But it doesn't seem to return anything I can work with? When I call it for the single image in the test above, I see in devtools that the response preview says Image from http://mysite.dev/show_image. (And again this is just for single file, haven't figured how to call multiple)
This is my code for uploading images to cloudinary.
let imageArr = [];
if (media) {
media && imageArr.push(media.thumbUrl);
}
let resultPromise = imageArr.map(async (img) => {
await cloudinary.uploader.upload(
img,
{ folder: process.env.STORE_NAME }, //Uploads to Specific Store Folder
async (err, result) => {
imageUrls.push(result.secure_url);
}
);
});
But the images are compressing automatically while uploading to 200 * 200 size. The actual size is 1000 * 1000.
https://res.cloudinary.com/sreeragcodes/image/upload/v1626531856/igowvkzckmlafwpipc22.png
Is this coding side error or should I configure something in cloudinary? I checked cloudinary but there's no configuration for this
In the code you shared, you aren't applying any incoming transformation which would be one reason why your images may be resized. If you log into your Cloudinary account and go to your Settings -> Upload tab and scroll down to the Upload Presets section, do you have any default upload preset selected? And if so, does that upload preset have any incoming transformations?
Unless you are applying an incoming transformation as part of a default upload preset, then this transformation wouldn't be applied on the Cloudinary level.
If you're not applying a default upload preset, then I would check the input images and perhaps store the images locally before uploading them to Cloudinary and seeing the size of those.
Note that you are uploading to Cloudinary the thumbUrl of each media. Could it be that this thumbnail URL is has been configured to be 200x200px and would explain why your images are such when uploaded to Cloudinary?
I am working with a service that allows the uploading of images to an S3 bucket, but it is not its only functionality. I would like to be aware if it is possible to know if an image is coming from the request and know if the image needs to be uploaded or not. Uploading is not mandatory in this service.
I was thinking in something like:
const sendPost = (req,res) => {
if(req.file) {
//Upload image
}
}
Well, I don't think it would be like that, but is this possible?
Like Mike suggests I am not sure if you just want to know if the file is an image or not. If you need to check the file type, try this library: https://github.com/mscdex/mmmagic
//use express-files and also try
if(Boolean(req.files.length)) {
//Upload image
}
Total nodejs newbie here. I am using meme-maker package to generate meme. However I want to create meme with image from url
var fileName = 'https://imgflip.com/s/meme/Futurama-Fry.jpg';
var memeMaker = require('meme-maker')
var options = {
image: fileName, // Required
outfile: 'meme.png', // Required
topText: 'top', // Required
bottomText: 'bottom', // Optional
}
memeMaker(options, function(err) {
if(err) throw new Error(err)
console.log('Image saved: ')
});
However I get error: Error: File does not exist: https://imgflip.com/s/meme/Futurama-Fry.jpg
How to read file from url and make meme?
If you go read the documentation of meme-maker you will see that it only supports local images and not URL's.
You will need to download the image first then use the local address. Go have a look at request
That library does not look like it supports URLs. The image param presumably takes a file path on the local system. If you want to use the URL to make a meme, you will have to:
Download that image from the URL using AJAX or something similar, store it to a file on the disk and get it's local path.
Pass the local file path of the file to the library
Get the generated meme path (and enable download if needed) and do clean up like deleting the old image, for example
So I have followed the Google's official sample for creating a Cloud Storage triggered Firebase Function that will create resized thumbnails from uploaded images and upload them to the Storage as well. Here it is simplified:
exports.generateThumbnail = functions.storage.object().onChange(event => {
// get the uploaded file data (bucket, name, type...)
// return if the file is not an image or name begins with "thumb_"
// download the uploaded image in a temporary local file,
// resize it using ImageMagick
// upload it to storage with the name "thumb_<filename>"
}
However, when the new thumbnail uploads, the function gets triggered again and so forth in a loop. They have avoided that by returning if the uploaded file has a "thumb_" prefix.
You then end up with two images (the original and the thumbnail) and I want to rewrite the existing image with the thumbnail so I only have one image with the original path.
I don't know how to go about this because I don't know how to evade the reupload loop without a name change. I can delete the original image after uploading the thumbnail but the link pointing to the original image is already returned and saved in the Realtime Database (these images are profile pictures for users).
After looking at the bucket.js documentation in the #google-cloud/storage npm module, I have finally managed to overwrite the original file/path with the thumbnail image and also avoid the loop,
It can be done by attaching custom metadata when uploading the thumbnail, and testing for that metadata when the function triggers the next time.
I will just post the changes I made, the rest is the same as in the linked sample.
Here's the testing:
const filePath = event.data.name
const metadata = event.data.metadata
if (metadata.isThumb) {
console.log('Exiting: Already a thumbnail')
return
}
And here's the part when the spawn promise returns:
return spawn(/* ... */)
}).then(_ => {
console.log('Thumbnail created locally.')
metadata.isThumb = true // We add custom metadata
const options = {
destination: filePath, // Destination is the same as original
metadata: { metadata: metadata }
}
// We overwrite the (bigger) original image but keep the path
return bucket.upload(/* localThumb */, options)
})