Convert BMP file to JPG in ParseCloud - javascript

I'm trying to convert some kind of images to jpg and save as a parse file.
Using the parse-image module works for GIF and PNG files, but I need to convert some BMP files too and this module does not work for .bmp files.
Is there anyway for me to do this image conversion on ParseCloud?
This is the code I used for parse-image:
Parse.Cloud.httpRequest({ url: url }).then(function(response) {
// Create an Image from the data.
var image = new Image();
return image.setData(response.buffer);
},function(error) {
console.log("Image not generated " + error.text);
}).then(function(image) {
// Format the image to a JPEG.
return image.setFormat("JPEG");
},function(error) {
console.log("Image set format failed");
})
Tks,

Related

Trying to Create a File from Blob but the Output file has Invalid Size

I am creating a canvas to rotate an image and creating a blob. But I need it as a file to upload it to server.
return new Promise((resolve, reject) => {
canvas.toBlob(blob => {
// returning an error
if (!blob) {
reject(new Error('Canvas is empty'));
return;
}
// blob.name = fileName;
// creating a Object URL representing the Blob object given
const rotatedImageUrl = window.URL.createObjectURL(blob);
resolve(rotatedImageUrl);
}, 'image/jpeg');
});
I am trying to create a file from the blob . I'm able to create it by using this snippet.
const rotatedFile = new File([img], originalFile.name, {
type: originalFile.type,
});
But the problem is generated file size is only 58 byte.
lastModified: 1644577677380
lastModifiedDate: Fri Feb 11 2022 17:07:57 GMT+0600 (Bangladesh Standard Time) {}
name: "IMG_4792.JPG"
size: 58
type: "image/jpeg"
webkitRelativePath: ""
I think the image is corrupted somehow.
Initially I thought canvas is somehow corrupting my image but I have also tried to create a file from an uploaded file converted to blob. That also gave me the same output. File size is not correct.
const file = e.target.files[0];
const blobUrl = URL.createObjectURL(file);
const generatedFile = new File([blobUrl], 'untitled', {
type: file.type,
});
Is there any solution? How can I properly create the file from the blob?
Why are you using the createObjectURL ?
You should resolve the blob directly resolve(blob); and then the file will correctly represent the image, instead of representing the objectURL.
What you are seeing is the length of the generated url. Something like "blob:https://........'

Save PNG image from Backend to Frontend to local Angular Project folder

I want to save a PNG image received from Backend (Java Project) to a folder inside my Angular Project. So far I can only save the image under Downloads/ folder of the PC and you can see how the file is downloaded. What I want is to silently download the image in my project (when I check the folder to see the new image stored).
Backend:
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("getImage")
public Response getImage() {
File dir = new File(Utilities.IMAGE_DIRECTORY);
File[] directoryListing = dir.listFiles();
String encodedImages = null;
// Get the first image stored in Backend project folder
try {
if (directoryListing != null) {
// Encode the image in Base64 and save it in a string
encodedImages = Base64
.getEncoder()
.withoutPadding()
.encodeToString(
Files.readAllBytes(directoryListing[0].toPath()));
}
} catch (IOException e) {
e.printStackTrace();
...
}
// Send the base64 string to Frontend
return Response
.status(Response.Status.OK)
.entity(encodedImages)
.build();
}
Frontend:
/* Extract Image */
getImage() {
this
.http
.get(this.baseUrl + "getImage", { responseType:
'text' })
.subscribe((res) => {
console.log("I received the image: \n" + res);
// Decode from base64 to PNG
var decodedImage = atob(res);
var blob = new Blob([decodedImage], { type: 'image/png' });
//this method saves the image in Downloads/ and it is not silent
saveAs(blob, 'imageFileName.png');
});
}
Since your user will not need the image it self why to download it? You don't need to download the image just for using it.
Only if your user need to download the image you could go with and "Save File" system.

Convert base64 to png in meteor app

I have a meteor application and in this one I get a base64 image. I want to save the image on a Digital Ocean instance, so I would convert it in a png or an other image format and send it to the server to get an url of the image.
But I didn't find a meteor package that does this.
Do you know how I can do that ?
I was running into a similar issue.
run the following:
meteor npm install --save file-api
This will allow the following code on the server for example:
import FileAPI from 'file-api';
const { File } = FileAPI;
const getFile = function(name,image){
const i = image.indexOf('base64,');
const buffer = Buffer.from(image.slice(i + 7), 'base64');
const file = new File({buffer: buffer, name, type: 'image/jpeg'});
return file;
}
Simply call it with any name of file you prefer, and the base64 string as the image parameter.
I hope this helps. I have tested this and it works on the server. I have not tested it on the client but I don't see why it wouldn't work.
I solved my problem using fs.writeFile from File System.
This is my javascript code on client side, I got a base64 image (img) from a plugin and when I click on my save button, I do this :
$("#saveImage").click(function() {
var img = $image.cropper("getDataURL")
preview.setAttribute('src', img);
insertionImage(img);
});
var insertionImage = function(img){
//some things...
Meteor.call('saveTileImage', img);
//some things...
}
And on the server side, I have :
Meteor.methods({
saveTileImage: function(fileData) {
var fs = Npm.require('fs');
var path = process.env.PWD + '/var/uploads/';
base64Data = fileData.replace(/^data:image\/png;base64,/, "");
base64Data += base64Data.replace('+', ' ');
binaryData = new Buffer(base64Data, 'base64').toString('binary');
var imageName = "tileImg_" + currentTileId + ".png";
fs.writeFile(path + imageName, binaryData, "binary", Meteor.bindEnvironment(function (err) {
if (err) {
throw (new Meteor.Error(500, 'Failed to save file.', err));
} else {
insertionTileImage(imageName);
}
}));
}
});
var insertionTileImage = function(fileName){
tiles.update({_id: currentTileId},{$set:{image: "upload/" + fileName}});
}
So, the meteor methods saveTileImage transform the base64 image into a png file and insertionTileImage upload it to the server.
BlobUrl, would it be a better option for you?
Save the images to a server as you like in base64 or whatever, and then when you are viewing the image on a page, generate the blobUrl of it. The url being used only at that time, preventing others from using your url on various websites and not overloading your image server ...

Converting Parse Image file to base64 for saving in zip file

I'm trying to download a group of image files that I am retrieving from Parse and save them to a zip file using JSZip. From this link it seems like I should be able to get the base64 encoding just by calling .base64 on my image object. I also tried toString('base64'). My zip file generates with files of the correct names but the contents of the files are empty. Am I missing something here?
Parse.Cloud.httpRequest({ url: result.get('image').url() }).then(function(response) {
var image = new Image();
image.setData(response.buffer);
var base64Image = image.data().base64;
zip.folder('images').file(imageName, base64Image, {base64: true});
return Parse.Promise.as('Success')
})
Finally managed to solve it by treating image.data() as asynchronous:
Parse.Cloud.httpRequest({ url: result.get('image').url() }).then(function(response) {
var image = new Image();
image.setData(response.buffer);
return image.data().then(function(data) {
zip.folder('images').file(imageName, data.toString('base64'), {base64: true});
return Parse.Promise.as('Success');
});
})

Crop and upload image on client-side without server-side code involve

As title said. The requirement is to be able to crop an image before uploading the cropped image to the server. All the work should be done on the client-side.
I have heard of the method to crop the image on the server and save it altogether.
But as i use Parse.com service. There is no supported for image manipulation on the server-side so i need to process it locally and upload the finished image directly to Parse.com service.
Example code would be very helpful.
Thanks.
The solution i used:
First I use a 3rd party javascript library to select the crop area like jCrop.
Once i got the coordinates (x1,x2,y1,y2), i draw a copy of an image to a canvas.
var canvas = document.getElementById('drawcanvas');
var context = canvas.getContext('2d');
canvas.width = canvas.width; // clear canvas
var imageObj = new Image();
imageObj.onload = function() {
// draw cropped image
// ...
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, sourceWidth, sourceHeight);
var dataURL = canvas.toDataURL();
};
imageObj.src = // image url
After i drew the canvas, i converted the canvas to a DataURL which is in base64 format.
Once i've got the DataURL, i use this function i found from the internet where it converts the DataURL to raw binary data.
DataURLConverter: function(data) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs
var byteString = atob(data.split(',')[1]);
// separate out the mime component
var mimeString = data.split(',')[0].split(':')[1].split(';')[0]
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return ia;
}
When we got the binary data, we then upload this directly to Parse.com.
Upload to parse with 'ia' as a data
var serverUrl = 'https://api.parse.com/1/files/' + fileName;
$.ajax({
type: "POST",
beforeSend: function(request) {
request.setRequestHeader("X-Parse-Application-Id", "App id");
request.setRequestHeader("X-Parse-REST-API-Key", "API Key");
request.setRequestHeader("Content-Type", "File type");
},
url: serverUrl,
data: ia,
processData: false,
contentType: false,
success: function(data) {
},
error: function(data) {
}
});
OK, I finally made it!!! after searching for a whole day!! Even now parse propose server side cropping, it's still interesting to have client side resizing.
Check this:
HTML5 Pre-resize images before uploading
Justin Levene's correction works really good!
But to work with Parse.com, you need to use
new Parse.File(name, {base64: somebase64string});
These codes works for me (for exemple, I uploaded a 2M photo, the re-sized photo would be like 150k):
var dataurl = canvas.toDataURL("image/jpeg");
var name = "image.jpg";
var parseFile = new Parse.File(name, {base64: dataurl.substring(23)});
parseFile.save().then(function() { ....
the "23" is all the letters before the real base64 string.
the result of dataurl is "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2......", we just need the part begin by "/9j/"
Good luck!
This might be an old post but if you found this answer (like me), you might want to know that Parse allows now to crop images server side.
For the latest code you should refer to their documentation: https://www.parse.com/docs/cloud_modules_guide#images
Parse Image Object (from Parse documentation):
var Image = require("parse-image");
Parse.Cloud.httpRequest({
url: object.get("profilePhoto").url(),
success: function(response) {
// The file contents are in response.buffer.
var image = new Image();
return image.setData(response.buffer, {
success: function() {
console.log("Image is " + image.width() + "x" + image.height() + ".");
},
error: function(error) {
// The image data was invalid.
}
})
},
error: function(error) {
// The networking request failed.
}
});
Crop Image (from Parse documentation):
// Crop the image to the rectangle from (10, 10) to (30, 20).
image.crop({
left: 10,
top: 10,
right: 30,
bottom: 20,
success: function(image) {
// The image was cropped.
},
error: function(error) {
// The image could not be cropped.
}
});
You can also scale, change image format, and create thumbnails.

Categories

Resources