How to save the blob for media file? - javascript

I successfully make the wave data and get type and wave like this below.
then I use createObjectURL and it gives me the url http://localhost:3003/5025f231-f5d0-49f5-9851-600376de0065 but there is nothing.
How can I make the real file??
Any help appreciated...
console.log(type); //wave
console.log(data); //Blob {size: 6791616, type: "audio/wav"}
if (type == 'wav'){
//how can I save the .wav file from blob and give the parameter for user?
var dlUrl = URL.createObjectURL(data)
console.log(dlUrl); //it shows http://localhost:3003/5025f231-f5d0-49f5-9851-600376de0065, but there is no 5025f231-f5d0-49f5-9851-600376de0065 file.
}

I believe you have to add a blob: in front of the url:
console.log(type); //wave
console.log(data); //Blob {size: 6791616, type: "audio/wav"}
if (type == 'wav'){
//how can I save the .wav file from blob and give the parameter for user?
var dlUrl = URL.createObjectURL(data)
console.log('blob:' + dlUrl); //it shows http://localhost:3003/5025f231-f5d0-49f5-9851-600376de0065 and there is 5025f231-f5d0-49f5-9851-600376de0065 file.
}

Related

Displaying a File() in the View from the controller

Is there a convenient way to display/Download a PDF file that is returned from the controller, the Controller retrieves a complex model and i am therefore using an Ajax call in order to call the ActionResult , the result received from the ActionResult is returned in the following format :
"%PDF-1.3
1 0 obj
[/PDF /Text /ImageB /ImageC /ImageI]
endobj
6 0 obj
....EOF"
Is there a way to assign this to a button to download , it is preferable that no Controller changes are required due to deployment issues with a client
i have tried to use a blob , however opening that blob returns a completely blank PDF
$.ajax({
type: "POST",
url: "Reporting/RenderRemoteReport",
data: { reportSetup: reportSetup },
success: function(response, status, xhr) {
debugger;
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([response], { type: type });
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
$("#DLButton").attr("href",downloadUrl);
}
});
If you are getting the blog data well then follow this might be helpful.
How to convert Blob to File in JavaScript

angular get image data and again append it to FormData

In angular 5 I am getting the images for hotelgallery from mongodb through my service. So basically the data what I am getting is like this
{
fieldname: "hotelgallery",
originalname: "e.jpg",
encoding: "7bit",
mimetype: "image/jpeg",
destination: "./public/",
encoding : "7bit",
filename : "1521139307413.jpg"
mimetype : "image/jpeg"
path : "public/1521139307413.jpg"
size : 66474
}
{
fieldname: "hotelgallery",
originalname: "e.jpg",
encoding: "7bit",
mimetype: "image/jpeg",
destination: "./public/",
encoding : "7bit",
filename : "1521139307413.jpg"
mimetype : "image/jpeg"
path : "public/1521139307413.jpg"
size : 66474
}
{
fieldname: "hotelgallery",
originalname: "j.jpg",
encoding: "7bit",
mimetype: "image/jpeg",
destination: "./public/",
encoding : "7bit",
filename : "1526753678390.jpg"
mimetype : "image/jpeg"
path : "public/1526753678390.jpg"
size : 66470
}
{
fieldname: "hotelgallery",
originalname: "k.jpg",
encoding: "7bit",
mimetype: "image/jpeg",
destination: "./public/",
encoding : "7bit",
filename : "7865456789413.jpg"
mimetype : "image/jpeg"
path : "public/7865456789413.jpg"
size : 66300
}
Now I want to again append those data to FormData but its not working.
The code what I have done so far
export class HotelEditComponent implements OnInit {
formData = new FormData();
ngOnInit() {
this.getOneHotel(this.route.snapshot.params['id']);
}
getOneHotel(id) {
this.http.get( this.apiUrl + '/api/hotel/' + id).subscribe(data => {
this.hotel = data;
this.appendImages(data['hotelimages']); //Here I am getting the data as mentioned here
});
}
public appendImages(imagedata) {
for (var i = 0; i < imagedata.length; i++) {
console.log(imagedata[i]);
this.formData.append('hotelgallery', imagedata[i], imagedata[i]['originalname']);
}
console.log(this.formData);
}
}
So can someone tell me how can I append the existing image data to FormData? Any help and suggestions will be really appreciable.
UseCase for this:
Actually I had used formData to upload images in angular. Now in the edit page the images are showing fine. But lets say a user edits some data and upload some images or remove some images. In that case I am getting the images from the database and again trying to upload them with formdata.
I have used this module and multer for nodejs to upload images with formData.
So can someone tell me how can I append the existing image data to FormData? Any help and suggestions will be really appreciable.
Actually, this approach need more add script solution. for example
1. Get Image Blob from server
Since you return detail object of images, not with the blob. You need have a endpoint to return as blob. (or if return as data buffer then it transform to blob you can use BlobUtil)
2. Put Blob to append form data
You need use blob to append in param 2 no a path, see documentation.
name
The name of the field whose data is contained in value.
value
The field's value. This can be a USVString or Blob (including subclasses
such as File).
filename Optional
The filename reported to the server
(a USVString), when a Blob or File is passed as the second parameter.
The default filename for Blob objects is "blob". The default filename
for File objects is the file's filename.
That what you need, but that is bad practice.
Let's say, you have 30 images to edit, then you need request blob endpoint to get those images blob to appends. But user only want to update 1 image, wasting time to request image blob, right?
For edit image usually we don't need append to file form (<input type="file" />).
Just show it as thumbnail to see what image uploaded and let file form empty.
What we do usually, thumbnail that image.
When user what to change, user put new image and replace old image with new want and update database.
if not, do nothing for image. (YAGNI)
FormData's append is silently failing here. You need to attach the 'image' as a blob. See the MDN docs.
formData.append('hotelgallery', new Blob([imagedata[i]], { type: "text/xml"}), imagedata[i]['originalname']);
Also, just printing formData won't show anything, instead try:
console.log(this.formData.getAll('hotelgallery'));
or
for (var value of this.formData.values()) {
console.log(value);
}
But lets say a user edits some data and upload some images or remove
some images. In that case I am getting the images from the database
and again trying to upload them with formdata.
So, you can pass object to universal method and on result get formData. Object data even can contain nested objects.
static createFormData(object: Object, form?: FormData, namespace?: string): FormData {
const formData = form || new FormData();
for (let property in object) {
if (!object.hasOwnProperty(property) || object[property] === undefined) {
continue;
}
const formKey = namespace ? `${namespace}[${property}]` : property;
if (object[property] instanceof Date) {
formData.append(formKey, object[property].toISOString());
} else if (typeof object[property] === 'object' && !(object[property] instanceof File)) {
this.createFormData(object[property], formData, formKey);
}
else if (typeof object[property] === 'number') {
let numberStr = object[property].toString().replace('.', ',');
formData.append(formKey, numberStr);
}
else {
formData.append(formKey, object[property]);
}
}
return formData;
}
}
In Component class:
export class HotelEditComponent implements OnInit {
formData = new FormData();
hotel: any;
...
ngOnInit() {
this.getOneHotel(this.route.snapshot.params['id']);
}
getOneHotel(id) {
this.http.get( this.apiUrl + '/api/hotel/' + id).subscribe(data => {
this.hotel = data;
});
}
postToServer() {
// or even can pass full `this.hotel` object
// this.helperService.createFormData(this.hotel)
this.formData = this.helperService.createFormData(this.hotel['hotelimages'])
this.service.post(this.formData);
}
...
}
It looks like you are trying to append a JSON array, since formData.append can only accept a string or blob, try the JSON.stringify() method to convert your array into a JSON string. (untested)
e.g. I think you can replace
this.appendImages(data['hotelimages']);
with
this.formData.append('hotelgallery', JSON.stringify(data['hotelimages']));
This is more of a design issue right now, rather then a tech problem. You are asking about posting FormData again and you want to fetch the images data again for that.
Now let's look at your current design.
User uploads 3 images of 4MB size each
On your edit page you downloads each of these images. Cost=12MB
On the edit page user deletes 2 images and adds 2 images. Cost=12MB
So final cost of updating 2 images of 8MB is 24MB. Which is a lot
Now before figuring out how to do FormData, figure out the right design for your app.
Consider the OLX site which allows you to post ads and later edit them. When you edit and remove a image, they call a API for removing the image
The ideal design in my opinion would be below
Submit all images in your create
For edit create a add and remove endpoint for the image
Submitting text data again on a edit form is ok, but submitting the same images data again on a edit form is never ok. Reconsider your design

How to embed base64 encoded data in image after downloading data from Azure Blob Storage in Javascript?

I'm trying to embed an image using the base64 data pattern, instead of a URL reference. I first download the data from Azure Blob storage, using the Azure Node.js SDK:
https://azure.microsoft.com/en-us/documentation/articles/storage-nodejs-how-to-use-blob-storage/#download-blobs
From what I can tell the data downloads as a string. But I'm not sure what to do with the string to get it into base64.
I need to encode the data as base64 and set the image source attribute. How do I do that?
Here is a snippet that shows what happens when I try to just embed the downloaded data directly:
cameraContainer.listBlobsSegmentedWithPrefix($routeParams.cameraId, path, null, options, function(error, result, response) {
result.entries.forEach(function(entry) {
$http.get(containerUrl + "/" + $routeParams.cameraId + "/" + entry.name + containerToken)
.then(function(successResponse) {
$scope.camera.imageUrl = "data:image/jpeg;base64," + successResponse.data;
}, function(errorResponse) {
});
});
});
I end up getting this error in the browser:
Also, if I try executing the following JS:
console.log(decodeURIComponent(successResponse.data));
I get this error:
Here is the raw data when logging to console
This is how I did it in our product. Please give it a try.
Essentially the data you're getting back is Uint8Array. First thing you would need to do is convert that array into string. You can use the following code to do so:
function Uint8ToString(array) {
var chunkSize = 0x8000;
var c = [];
for (var i = 0; i < array.length; i += chunkSize) {
c.push(String.fromCharCode.apply(null, array.subarray(i, i + chunkSize)));
}
return c.join('');
}
Next, you need to convert this string in base64 format. Here's how I'm doing it currently:
var blobContentsAsString = Uint8ToString(blobContents);
var blobContentsAsBase64String = btoa(blobContentsAsString);
$scope.camera.imageUrl = "data:image/jpeg;base64," + blobContentsAsBase64String;
Do give it a try.

Struts2 Action Form Data Maximum Size for Image Upload using Base64

I have a Struts2 action that receives a string containing an image in Base64 and another string for the image name.
Everything works well for small sized images. But when I try to send a larger image, the Base64 and the image name strings are set to null in the action implementation.
In search for a solution I found that the default maximum size for the file upload is 2 MB. This limit can be increased with the following properties:
<constant name="struts.multipart.maxSize" value="104857600" />
<param name="maximumSize">52428800</param>
<param name="fileUpload.maximumSize">52428800</param>
However this is not working. Probably this implementation is not a file upload but a two string POST request.
Is there a way I can increase the size of the post request? Or the problem is something else?
public class GalleryAction extends BaseAction {
private String imageBase64;
private String imageName;
...
public final String uploadOperation() throws Exception {
if (this.imageBase64 == null || this.imageBase64.length() == 0
|| this.imageName == null || this.imageName.length() == 0) {
throw new Exception("Invalid argument");
}
byte[] decodedBytes = Base64Decoder.decode2bytes(this.imageBase64);
InputStream is = new ByteArrayInputStream(decodedBytes);
Graphics graphics = MGraphics.insertImageToDataBase(this.imageName, is);
// Issue server to sync image.
RestUtils.syncImage(graphics.getId());
JSONObject response = new JSONObject();
response.put("statusCode", "0");
jsonString = response.toString();
return JSON_RESPONSE;
}
...
}
EDIT:
I forgot to publish the code for the image upload.
Gallery.prototype.upload = function(base64, imageName) {
var galleryObject = this;
galleryObject.loadingCallback(true);
$.post(this.urlBase + "/upload", {
"imageBase64" : base64.match(/,(.*)$/)[1],
"imageName" : imageName
}, function(data) {
galleryObject.handlerErrorMessageCallback();
galleryObject.loadingCallback(false);
galleryObject.refreshImageGalleryCallback();
}, "json")
.fail(function() {
galleryObject.handlerErrorMessageCallback("error.upload.image");
galleryObject.loadingCallback(false);
});
}
The HTTP protocol specifications don't set a limit to the size of a POST message. However, your application server does it (mainly to prevent DDoS attacks).
Usually this threshold is 10 MegaBytes, and it is the one you are hitting. You should then be able to customize this setting according to your AS specs.
That said, this is not encouraged, and could lead to security vulnerabilities.
The best thing would be to:
use multipart/form-data over application/x-www-form-urlencoded;
use File instead of String since what you're uploading are files, and not strings.
I changed the upload method to Form data.
Gallery.prototype.upload = function(base64, imageName) {
var galleryObject = this;
galleryObject.loadingCallback(true);
var request = new FormData();
request.append("imageBase64", base64.match(/,(.*)$/)[1]);
request.append("imageName", imageName);
$.ajax({url:this.urlBase + "/upload",
data: request,
type: "POST",
processData: false,
contentType: false,
success: function(result)
{
galleryObject.handlerErrorMessageCallback();
galleryObject.loadingCallback(false);
galleryObject.refreshImageGalleryCallback();
}
}).fail(function() {
galleryObject.handlerErrorMessageCallback("error.upload.image");
galleryObject.loadingCallback(false);
});
}
Using this post method the following property on strus.xml must exists
<constant name="struts.multipart.maxSize" value="104857600" />

Publishing photo as multipart/form-data to Facebook using Javascript graph API v2.5

Facebook's Graph API (v2.5) User Photo Edge says that there are two separate ways of publishing photos to Facebook:
1: Attach the photo as multipart/form-data. The name of the object doesn't matter, but historically people have used source as the parameter name for the photo.How this works depends on the SDK you happen to be using to do the post.
2: Use a photo that is already on the internet by publishing using the url parameter:
FB.api(
"/me/photos",
"POST",
{
"url": "{image-url}"
},
function (response) {
if (response && !response.error) {
/* handle the result */
}
}
);
I need to use the first method (multipart) as I have got the base64 image data from canvas.
This seems to be confusing as I don't find the documentation very informative. I understand that the urlData of image is to be encoded in some format in the multipart data along with other parameters. I fail to find any working sample code/proper explanation on how to do this using Javascript SDK & graph api v2.5; even after an exhaustive search on stackoverflow. I have seen a various partially answered/unanswered questions regarding this on stackoverflow...But I still fail to get it work.
Please help. Thanks !
Similar Questions
Facebook Javascript Form Data Photo Upload: requires upload file error
Javascript: Upload image from Canvas to FB via Graph API
Upload Base64 Image Facebook Graph API - Not clear if Javascript Api has been here
[Edit] - Code I have already tried.
var ctx = document.getElementById('canvas2');
urldata=ctx.toDataURL("image/png");
FB.api('/photos', 'POST', {
message: 'testing Graph API',
access_token: accessToken,
url: urldata,
no_story:true
}, function (response) {
if (!response || response.error) {
console.log('Error occured:' + response.error.message);
} else {
alert('Post ID: ' + response.id);
}
}
);
Response -"
Error occured:(#324) Missing or invalid image file "
I was not able to use the JS SDK with this, but it works with a simple AJAX request (with the Fetch API, axios or something else).
First, turn the Canvas Image into a Blob with the following function:
const dataURItoBlob = (dataURI) => {
let byteString = atob(dataURI.split(',')[1]);
let ab = new ArrayBuffer(byteString.length);
let ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {
type: 'image/jpeg'
});
}
After that, you can use the blog with FormData:
formData.append('source', blob);
Source: http://www.devils-heaven.com/facebook-javascript-sdk-photo-upload-from-canvas/

Categories