I’m using DropzoneJS to facilitate the upload of files (images) as part of a .net core application. I want to be able to send the dimensions (width and height) of the file to the .net controller. But I haven’t been able to figure out how to obtain the media file dimensions after the file has been resized.
Here is the js declaration:
product_media_dropzode_ctrl = new Dropzone("#product_form_ctrl", {
paramName: "file",
maxFilesize: 3,
maxFiles: 10,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
autoProcessQueue: true,
uploadMultiple: false,
parallelUploads: 100,
resizeWidth: 1920,
resizeHeight: 1080,
resizeMimeType: 'image/jpeg',
resizeQuality: 1.0,
resizeMethod: 'crop',
accept: function (file, done) {
if (UploadedNumberFiles() > maxNumberOfMediaFile) {
done("The maximum number of files has been reached.");
}
else {
done();
}
},
init: function () {
this.on("thumbnail", function (file, dataUrl) {
**console.log("widthXheight:" + file.width + "X" + file.height);**
$('#product_width_hidden_ctrl').val(file.width);
$('#product_height_hidden_ctrl').val(file.height);
})
this.on("success", function (file, response) {
HandleUploadSuccess(response);
});
this.on('error', function (file, response) {
HandleUploadError(response);
});
},
});
}
If I upload a file 4151X2000, the file will be resized to 1920X1080, however the line below will display 4151X2000 instead of 1920X1080. If I upload a file 1800X1200, 1800X1200 is display instead of 1800X1080 which is the dimension of the file after being resized
**console.log("widthXheight:" + file.width + "X" + file.height);**
Is there a way to capture the file dimensions after the image has been resized and before the file is submitted to the server?
Related
I'm trying to convert html element into pdf. Everything is working fine , but it doesn't render the aws image in pdf.
Even though if i add a local path to the img src attribute then it render's that image in pdf.
const invoiceSection = $("#customer_invoice_bill");
let invoiceName = invoiceSection.data("invoiceName");
$("#btnDownloadInvoice").on("click", function () {
var pdfConf = {
pagesplit: true,
background: "#fff",
image: { type: "webp", quality: 0.98 }, // as per req
html2canvas: { dpi: 300, letterRendering: true, useCORS: true },
};
var pdf = new jsPDF("p", "pt", [
invoiceSection.height() + 100,
invoiceSection.width(),
]);
pdf.addHTML(invoiceSection, pdfConf, function () {
pdf.save(`${invoiceName}.pdf`);
});
});
this is the html element
https://i.stack.imgur.com/gEua9.png
this is how pdf is rendered without image. but it rendered the last image which is below(signature) as i have assign a local path to the src=""
https://i.stack.imgur.com/M3qrT.png
I am implementing direct upload with Shrine, jquery.fileupload and cropper.js
in the add portion I am loading the image from the file upload to modal, define the cropper and show the modal
if (data.files && data.files[0]) {
var reader = new FileReader();
var $preview = $('#preview_avatar');
reader.onload = function(e) {
$preview.attr('src', e.target.result); // insert preview image
$preview.cropper({
dragMode: 'move',
aspectRatio: 1.0 / 1.0,
autoCropArea: 0.65,
data: {width: 270, height: 270}
})
};
reader.readAsDataURL(data.files[0]);
$('#crop_modal').modal('show', {
backdrop: 'static',
keyboard: false
});
}
Then on the modal button click I get the cropped canvas call on it toBlob and submit to S3
$('#crop_button').on('click', function(){
var options = {
extension: data.files[0].name.match(/(\.\w+)?$/)[0], // set extension
_: Date.now() // prevent caching
};
var canvas = $preview.cropper('getCroppedCanvas');
$.getJSON('/images/cache/presign', options).
then(function (result) {
data.formData = result['fields'];
data.url = result['url'];
data.paramName = 'file';
if (canvas.toBlob) {
canvas.toBlob(
function (blob) {
var file = new File([blob], 'cropped_file.jpeg');
console.log('file', file);
data.files[0] = file;
data.originalFiles[0] = data.files[0];
data.submit();
},
'image/jpeg'
);
}
});
});
After the upload to S3 is done I am writing to image attributes to hidden field, closing the modal and destroying the cropper
done: function (e, data) {
var image = {
id: data.formData.key.match(/cache\/(.+)/)[1], // we have to remove the prefix part
storage: 'cache',
metadata: {
size: data.files[0].size,
filename: data.files[0].name.match(/[^\/\\]*$/)[0], // IE returns full path
// mime_type: data.files[0].type
mime_type: 'image/jpeg'
}
};
console.log('image', image);
$('.cached-avatar').val(JSON.stringify(image));
$('#crop_modal').modal('hide');
$('#preview_avatar').cropper('destroy');
}
An chrome everything worked fine from the very beginning, but then I figured out the safari has no toBlob functionality.
I found this one:
https://github.com/blueimp/JavaScript-Canvas-to-Blob
And toBlob is not a function error was gone..
Now I can not save the image due to some mime type related issue.
I was able to find out the exact location where it fails on safari but not chrome.
determine_mime_type.rb line 142
on line 139 in the options = {stdin_data: io.read(MAGIC_NUMBER), binmode: true}
the stdin_data is empty after the io.read
Any ideas?
Thank you!
UPDATE
I was able to figure out that the url to the cached image returned by the
$.getJSON('/images/cache/presign', options)
returns empty file when cropped and uploaded from safari.
So as I mentioned in the question safari uploaded empty file once it was cropped by cropper.js.
The problem clearly originated from this block:
if (canvas.toBlob) {
canvas.toBlob(
function (blob) {
var file = new File([blob], 'cropped_file.jpeg');
console.log('file', file);
data.files[0] = file;
data.originalFiles[0] = data.files[0];
data.submit();
},
'image/jpeg'
);
}
I found in some comment on one of the articles I read that safari does some thing like "file.toString" which in my case resulted in empty file upload.
I appended the blob directly without creating a file from it first and everything worked fine.
if (canvas.toBlob) {
canvas.toBlob(
function (blob) {
data.files[0] = blob;
data.files[0].name = 'cropped_file.jpeg';
data.files[0].type = 'image/jpeg';
data.originalFiles[0] = data.files[0];
data.submit();
},
'image/jpeg'
);
}
I'm building a hybrid app in ionic, which runs over cordova. I use the $cordovaCamera plugin to capture images from the phone, either by selecting from the phone's gallery or by using the camera to take a picture.
I then send that image using Restangular to my server, and when that action finishes, I want to display a status message on the screen.
My problem: All of the above works perfectly on Android. On iOS, it is working only when the image is selected from the gallery, but not when the image is directly captured from the phone. In that case, the image is correctly transferred to the server, the request returns a 201 Created just as it should - but the then() callback function is never entered.
If anyone can explain this behavior, that would be awesome...my second best would be to capture the image on the iPhone, save to gallery, and then attempt to retrieve the last saved image, but I haven't been able to figure out how to yet and I'd rather just get this working.
Update: I've narrowed it down to the Restangular part - if instead of calling the Restangular upload function, I use $http, the callback is triggered as expected and all is good...so that's what I'm going to do, but if anyone can tell me what the problem was I'd be grateful.
Relevant code:
/** cameraService functions **/
//when the user chooses to snap a picture from the camera
takePicture: function(){
var options = {
quality: 50,
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions
};
return $cordovaCamera.getPicture(options).then(
function(imageData) {
return imageData;
},
function(err) {
console.log("error", err);
});
},
//when the user chooses to select image from the gallery
choosePicture: function(){
var options = {
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY
};
return $cordovaCamera.getPicture(options).then(
function(imageData) {
return imageData;
},
function(err) {
console.log("error", err);
});
},
uploadPicture: function(imageSource, caption, is_logo){
if (typeof is_logo == 'undefined') is_logo = false;
var upload_object = {
caption: caption,
source: imageSource,
is_logo: is_logo
};
//apiService is my wrapper for Restangular
return apiService.uploadFile(loadingService.getClientUrl('images'), upload_object);
},
/**apiService uploadFile - apparently the problem is here ***/
uploadFile: function(baseElem, object, route, path){
var headers = apiFunctions.setHeaders({'Content-Type': undefined});
//this DOES NOT WORK (on iPhone with image from camera) - request completes but callback not triggered
return Restangular.all(baseElem).customPOST(object, path, route, headers);
//this works fine:
return $http.post('https://api.mysite.dev/v1/clients/'+localStorageService.getValue('client_id')+'/images', JSON.stringify(object), {headers:headers}
);
},
/** controller functions **/
$scope.takePicture = function () {
cameraService.takePicture().then(function (imageData) {
$scope.data.imageSource = imageData;
});
};
$scope.choosePicture = function () {
cameraService.choosePicture().then(function (imageData) {
$scope.data.imageSource = imageData;
});
};
$scope.uploadPicture = function () {
cameraService.uploadPicture($scope.data.imageSource, $scope.data.caption)
.then(function (response) { //this is never entered if image is captured from camera on iPhone
$ionicScrollDelegate.scrollTop();
$scope.data.caption = '';
$scope.data.imageSource = '';
if (response.data.response.is_success.data_value == true) {
$scope.messages.success.push("Photo uploaded successfully");
} else {
$scope.messages.failure.push("Error uploading photo.");
}
});
}
I'm having a couple of issues I tell them. I am taking a picture with the plugin Camera with phonegap and that suits me, what I do with that image is about putting another picture above I'm doing it through canvas and the problem is this left images to make it look. Zoom or something applied.
Original image
https://scontent-mia.xx.fbcdn.net/hphotos-xpf1/v/t1.0-9/10987455_403839709795958_6331116352644016645_n.jpg?oh=df8fc2cef2c1255a6babec94b3a2056d&oe=557E3520
Canvas image
https://scontent-mia.xx.fbcdn.net/hphotos-xpf1/v/t1.0-9/11064814_403839689795960_2255378534429169909_n.jpg?oh=9c0ebab7c6e9911cc28695fa80cc3033&oe=5581D16B
Also, when I take photos I can not take it whole, something I do not understand that there will be cutting the image.
Here's the setup method camera and canvas.
$scope.guardarFoto = function(){
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("img_foto");
var img2 = document.getElementById("img_foto2");
ctx.drawImage(img,0,0);
ctx.drawImage(img2,0,0);
window.canvas2ImagePlugin.saveImageDataToLibrary(
function(msg){
console.log(msg);
},
function(err){
console.log(err);
},
document.getElementById('myCanvas')
);
}
Camera.DestinationType = {
DATA_URL : 0, // Return image as base64-encoded string
FILE_URI : 1, // Return image file URI
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
};
Camera.PictureSourceType = {
PHOTOLIBRARY : 0,
CAMERA : 1,
SAVEDPHOTOALBUM : 2
};
Camera.EncodingType = {
JPEG : 0, // Return JPEG encoded image
PNG : 1 // Return PNG encoded image
};
Camera.MediaType = {
PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
ALLMEDIA : 2
};
Camera.Direction = {
BACK : 0, // Use the back-facing camera
FRONT : 1 // Use the front-facing camera
};
$scope.getPhoto = function() {
var options = {
quality: 100,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 500,
targetHeight: 500,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: true,
correctOrientation: true
};
Camera.getPicture(options).then(function(imageURI) {
console.log(imageURI);
$scope.lastPhoto = imageURI;
}, function(err) {
// error
});
};
Hi i'm trying to capture a photo and save it permanently to the filesystem. Taking the photo works so far, but it seems it doesn't save it permanently to the filesystem. After i restart the app, the pictures are gone.
The path of the picture is saved to my WebSQL Database (which works without problems)
Here is the part of my code:
function capturePhoto() {
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50,
destinationType: destinationType.FILE_URI, saveToPhotoAlbum: true });
}
function onFail(message) {
console.log('Failed because: ' + message);
}
function onPhotoDataSuccess(imageURI) {
movePic(imageURI);
}
function movePic(file){
window.resolveLocalFileSystemURI(file, resolveOnSuccess, resOnError);
}
//Callback function when the file system uri has been resolved
function resolveOnSuccess(entry){
var d = new Date();
var n = d.getTime();
//new file name
var newFileName = n + ".jpg";
var myFolderApp = "LeadAppPhotos";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
//The folder is created if doesn't exist
fileSys.root.getDirectory( myFolderApp,
{create:true, exclusive: false},
function(directory) {
entry.moveTo(directory, newFileName, successMove, resOnError);
},
resOnError);
},
resOnError);
}
//Callback function when the file has been moved successfully
function successMove(entry) {
//put the path url in a div so i can save it later to my websql database
$('#hidden_photo').val(entry.fullPath);
}
function resOnError(error) {
alert(error.code);
}
What's my mistake?