I'm using Cropper to crop the images in a circular shape from this example:
https://github.com/fengyuanchen/cropperjs/blob/master/examples/crop-a-round-image.html
Here is a fiddle: http://jsfiddle.net/7hsr98w4/7/
That's how the cropped image looks like:
<img src="data:image/png;base64,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">
Then I use Ajax to send that blob to PHP to upload that image:
document.getElementById('button').addEventListener('click', function(){
var imgurl = cropper.getCroppedCanvas().toDataURL();
cropper.getCroppedCanvas().toBlob(function (blob) {
var formData = new FormData();
formData.append('avatar', blob);
// Use `jQuery.ajax` method
$.ajax('upload.php', {
method: "POST",
data: formData,
processData: false,
contentType: false,
success: function (response) {
console.log(response);
},
error: function () {
console.log('Upload error');
}
});
});
});
This code could be found here:
https://github.com/fengyuanchen/cropperjs#getcroppedcanvasoptions
In upload.php:
print_r($_FILES);
if(isset($_FILES['avatar']) and !$_FILES['avatar']['error']){
file_put_contents("uploads/image.png", file_get_contents($_FILES['avatar']['tmp_name']));
}
exit();
That's the response from print_r($_FILES):
Array
(
[avatar] => Array
(
[name] => blob
[type] => image/png
[tmp_name] => C:\xampp\tmp\php2BDA.tmp
[error] => 0
[size] => 2135
)
)
When I console.log() blob, I get and Object:
Blob(2135) {size: 2135, type: "image/png"}
But when I view the image on the uploads folder, It's a rectangular image not circular.
Here is how it's previewed after cropping:
And that's how it's previewed on uploads folder:
Both images(previewed and saved) are 360x360.
How to save the cropped image in circular shape like how it's previewed after cropping?
You need to add rounding box css for .cropper-crop-box also
.cropper-crop-box, .cropper-view-box {
border-radius: 50%;
}
If you want circular view box you can use this
.cropper-view-box {
box-shadow: 0 0 0 1px #39f;
outline: 0;
}
UPDATE:
Sorry I misunderstood your question actually what you wanted was pretty straightforward
You already have getRoundedCanvas() which gets you the rounded version of crop, so just need to use it in your ajax call like
document.getElementById('button').addEventListener('click', function(){
var imgurl = cropper.getCroppedCanvas().toDataURL();
//only this line is changed
getRoundedCanvas(cropper.getCroppedCanvas()).toBlob(function (blob) {
var formData = new FormData();
formData.append('avatar', blob);
// Use `jQuery.ajax` method
$.ajax('upload.php', {
method: "POST",
data: formData,
processData: false,
contentType: false,
success: function (response) {
console.log(response);
},
error: function () {
console.log('Upload error');
}
});
});
});
I think that this function getroundedcanvas() doesn't exist with the jquery-cropper.js, if it was you, you have already done a great job with your function, I really needed it badly this is what I added and uploaded it with PHP.
case 'getCroppedCanvas':
if (result) {
// Upload cropped image to server if the browser supports `HTMLCanvasElement.toBlob`.
// The default value for the second parameter of `toBlob` is 'image/png', change it if necessary.
// Round
var roundedCanvas = getRoundedCanvas(result);
// Show
$('img.MyImage').attr('src',roundedCanvas.toDataURL());
var roundedBlob ;
roundedCanvas.toBlob((blob) => {
roundedBlob = blob;
});
result.toBlob((blob) => {
const formData = new FormData();
// Pass the image file name as the third parameter if necessary.
formData.append('UploadPhoto', blob, 'profil.png' );
formData.append('CircleBlob', roundedBlob, 'circle.png' );
$.ajax(document.location.pathname, {
method: 'POST',
data: formData,
processData: false,
contentType: false,
success(response) {
console.log(response);
console.log('Upload success');
$('#imgResizeModal').modal("hide");
},
error() {
console.log('Upload error');
},
});
}/*, 'image/png' */);
}
break;
Related
I am using cropper.js. I would like to upload the original image and the cropped coordinates(x,y,width,height) not the cropped image. What is the preferred way to do that?
Thanks.
For the client side of this question, here is code I use to package up the crop box data and ship it off to the server. See esp:
formData.append('last_crop', JSON.stringify($imageBox.cropper('getCropBoxData')));
$('#crop_button').click(function(){
// Upload cropped image to server if the browser supports `HTMLCanvasElement.toBlob`.
// Store crop coordinates to db for future visit.
var canvas = $imageBox.cropper('getCroppedCanvas');
canvas.toBlob(function (blob) {
var formData = new FormData();
formData.append('croppedImage', blob); // 'croppedImage' is the sent filename
formData.append('last_crop', JSON.stringify($imageBox.cropper('getCropBoxData')));
$.ajax('{% url 'profile_crop_avatar' %}', {
method: "POST",
data: formData,
processData: false,
contentType: false,
success: function () {
console.log('Upload success');
},
error: function () {
console.log('Upload error');
}
});
}, "image/jpeg", 0.75);
// Also update masthead image after crop
$('#masthead-avatar').attr('src', canvas.toDataURL());
});
On the server side (Django) I handle and store the coords with:
# Save new image and crop coords to profile
p = request.user
p.last_crop_coords = request.POST.get('last_crop')
p.save()
i'm trying encode the document generated in the attached code, but nothing happens, not generate error but neither encodes the file, and the ajax request is never executed
what is the correct way?
html2canvas(document.getElementById("workAreaModel"), {
onrendered: function(canvas)
{
var img = canvas.toDataURL("image/png");
var doc = new jsPDF("l", "pt", "letter");
doc.addImage(img, 'JPEG',20,20);
var fileEncode = btoa(doc.output());
$.ajax({
url: '/model/send',
data: fileEncode,
dataType: 'text',
processData: false,
contentType: false,
type: 'GET',
success: function (response) {
alter('Exit to send request');
},
error: function (jqXHR) {
alter('Failure to send request');
}
});
}
});
First, jsPDF is not native in javascript, make sure you have included proper source, and after having a peek on other references, I think you don't need btoa() function to convert doc.output(), just specify like this :
doc.output('datauri');
Second, base-64 encoded string is possible to contain ' + ' , ' / ' , ' = ', they are not URL safe characters , you need to replace them or you cannot deal with ajax .
However, in my own experience, depending on file's size, it's easy to be hell long ! before reaching the characters' length limit of GET method, encoded string will crash your web developer tool first, and debugging would be difficult.
My suggestion, according to your jquery code
processData: false,
contentType: false
It is common setting to send maybe File or Blob object,
just have a look on jsPDF, it is availible to convert your data to blob :
doc.output('blob');
so revise your code completely :
var img = canvas.toDataURL("image/png");
var doc = new jsPDF("l", "pt", "letter");
doc.addImage(img, 'JPEG',20,20);
var file = doc.output('blob');
var fd = new FormData(); // To carry on your data
fd.append('mypdf',file);
$.ajax({
url: '/model/send', //here is also a problem, depends on your
data: fd, //backend language, it may looks like '/model/send.php'
dataType: 'text',
processData: false,
contentType: false,
type: 'POST',
success: function (response) {
alter('Exit to send request');
},
error: function (jqXHR) {
alter('Failure to send request');
}
});
and if you are using php on your backend , you could have a look on your data information:
echo $_FILES['mypdf'];
This code is for capturing Html page from screen and save as Pdf and send to back end api As blob
const filename = 'form.pdf';
const thisData = this;
this.printElement = document.getElementById('content');
html2canvas(this.printElement).then(canvas => {
this.pdfData = new jsPDF ('p', 'mm', 'a4');
this.imageHeight = canvas.height * 208 / canvas.width;
this.pdfData.addImage(canvas.toDataURL('image/png'), 'PNG', 0, 0, 208, this.imageHeight);
this.pdfData.save(filename);
this.uploadFile(this.pdfData.output('blob'));
});
}
uploadFile(pdfFile: Blob) {
this.uploadService.uploadFile(pdfFile)
.subscribe(
(data: any) => {
if (data.responseCode === 200 ) {
//succesfully uploaded to back end server
}},
(error) => {
//error occured
}
)
}
Dropzone.js seems to be uploading images as multi-part form data. How do I get it to upload images in the same way an image upload would work with cURL or a binary image upload with Postman?
I'm getting a pre-signed URL for S3 from a server. The pre-singed URL allows an image upload, but not form fields:
var myDropzone = new Dropzone("#photo-dropzone");
myDropzone.options.autoProcessQueue = false;
myDropzone.options.autoDiscover = false;
myDropzone.options.method = "PUT";
myDropzone.on("addedfile", function ( file) {
console.log("Photo dropped: " + file.name );
console.log("Do presign URL: " + doPresignUrl);
$.post( doPresignUrl, { photoName: file.name, description: "Image of something" })
.done(function( data ) {
myDropzone.options.url = data.url
console.log(data.url);
myDropzone.processQueue();
});
});
If I use the returned URL with Postman and set the body to binary and attach the image, then the upload works fine. However, if the Dropzone library uses the same URL to upload the image to S3 then I get a 403 because S3 does not expect form fields.
Update:
An Ajax alternative works as below with a S3 signed url, but Dropzone.js does not seem willing to put the raw image data in the PUT message body.
$.ajax( {
url: data.url,
type: 'PUT',
data: file,
processData: false,
contentType: false,
headers: {'Content-Type': 'multipart/form-data'},
success: function(){
console.log( "File was uploaded" );
}
});
Set maxFiles to 1.
Dropzone.autoDiscover = false;
dzAllocationFiles = new Dropzone("div#file-container", {
url: "api.php?do=uploadFiles"
, autoDiscover: false
, maxFiles: 1
, autoQueue: true
, addRemoveLinks: true
, acceptedFiles: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
});
dzAllocationFiles.on("success", function (file, response) {
// Success Operations
});
dzAllocationFiles.on("maxfilesexceeded", function (file, response) {
allocationFileNames = [];
this.removeAllFiles();
this.addFile(file);
});
Add below options, then working.
myDropzone.options.sending = function(file, xhr) {
var _send = xhr.send;
xhr.send = function() {
_send.call(xhr, file);
}
}
I have asp.net mvc 4 application. In that application I have form , in that form I have summernote rich text editor. But in this editor I have option to upload images to this editor.
But Once I fill rest of the fields and sumbit the this form. Its not saving images that I uploaded through summernote editor .
I want to upload images to following path ~/Content/Images/
and keep the path as ~/Content/Images/Image_Name.JPG in database field
So I tried to create my solution as following by following this solution and GitHub Issue reported here
from Viewpage
<div class="form-group">
#Html.TextAreaFor(m => m.Field_Value, new { #class = "form-control summernote"})
</div>
Controller method
[HttpPost]
public byte[] UploadImage(HttpPostedFileBase file)
{
Stream fileStream = file.InputStream;
var mStreamer = new MemoryStream();
mStreamer.SetLength(fileStream.Length);
fileStream.Read(mStreamer.GetBuffer(), 0, (int)fileStream.Length);
mStreamer.Seek(0, SeekOrigin.Begin);
byte[] fileBytes = mStreamer.GetBuffer();
Stream stream = new MemoryStream(fileBytes);
//string result = System.Text.Encoding.UTF8.GetString(fileBytes);
var img = Bitmap.FromStream(stream);
Directory.CreateDirectory("~//Content//Images//" + img);
return fileBytes;
}
this is script
<script type="text/javascript">
$('.summernote').summernote({
height: 200, // set editable area's height
focus: true, // set focus editable area after Initialize summernote
onImageUpload: function (files, editor, welEditable) {
var formData = new FormData();
formData.append("file", files[0]);
$.ajax({
url: "#Url.Action("Home", "UploadImage")",
data: formData,
type: 'POST',
cache: false,
contentType: false,
processData: false,
success: function (imageUrl) {
if (!imageUrl) {
debugger;
// handle error
return;
}
editor.insertImage($editable, imageUrl);
},
error: function () {
// handle error
}
});
}
});
this once also, its not showing whether image uploaded to editor at all
I updated your script, and it works for me (check the changes on code comments):
<script type="text/javascript">
var editor = // 1st change: will need this variable later
$('.summernote').summernote({
height: 200,
focus: true,
callbacks: { // 2nd change - onImageUpload inside of "callbacks"
onImageUpload: function (files) { // 3rd change - dont need other params
var formData = new FormData();
formData.append("file", files[0]);
$.ajax({
url: "#Url.Action("Home", "UploadImage")",
data: formData,
type: 'POST',
cache: false,
contentType: false,
processData: false,
success: function (imageUrl) {
if (!imageUrl) {
// handle error
return;
}
// 4th change - create img element and add to document
var imgNode = document.createElement('img');
imgNode.src = imageUrl;
editor.summernote('insertNode', imgNode);
},
error: function () {
// handle error
}
});
}
}
});
</script>
I need to read data from FormData? I try to read something like someFormatData["valueName"] but it not working.
options["fileId"] or options["file"] does not work. Also I try options.fileId same result:
function upload(file, fileId, callback) {
var formData = new FormData();
formData.append("file", file);
formData.append("fileID", fileId);
$.ajax({
url: '/url',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
callback(response);
}
});
}
asyncTest("test upload chunk", function() {
var blob = new Blob(["Hello world!"], { type: "text/plain" }),
options = null,
fileID ="someFileID",
response;
jQuery.ajax = function(param) {
options = param; // THIS is FormData object
// how to read fileId and file from here
};
upload(blob, fileID, function (data) {
response = data;
});
options.success({
someProp: 'responseFromServer'
});
setTimeout(function() {
QUnit.equal(options, "dataTosend", "parameters is OK");
QUnit.equal(response["someProp"], "responseFromServer", "Response ok");
start();
},1000);
});
If you take your FormData object you can use a few different methods on it… What you are looking for is
formData.get()
or
formData.getAll()
https://developer.mozilla.org/en-US/docs/Web/API/FormData
Note that the get() method is not fully supported on all browsers.
You can read using this
formData.get('fileId') // to read Id
formData.get('file') // to read the file
Another way to list all entries of a FormData :
for(const entry of formData){
console.log(entry); // Array: ['entryName', 'entryValue']
}