My code is cropping an image but cropped image is very large. I'm using the Cropit jQuery plugin.
My View has an div mask on the image. When the form post, the hidden input has cropped image through the following script.
<div class="image-editor" style="margin-left:120px; margin-bottom:25px; margin-top:25px;">
<input id="fileinput" type="file" name="filex" class="cropit-image-input">
<div class="cropit-image-preview" style="background-image:url()"></div>
<input type="range" class="cropit-image-zoom-input">
<input type="hidden" name="image-data" value="" class="hidden-image-data" />
<button type="submit" class="export">Crop</button>
</div>
<script>
$(function () {
$('.image-editor').cropit({});
$('.export').click(function () {
var imageData = $('.image-editor').cropit('export');
$('.hidden-image-data').val(imageData);
});
});
</script>
In my Controller Create function gets cropped image via Request and write to file but the new file is too large. For example, input file is 50kb and cropped output file is 600kb. Normally the cropped image must be smaller than input image. How to fix the problem?
[HttpPost]
public ActionResult Create()
{
var dataurl = Request["image-data"];
var data = dataurl.Substring(dataurl.IndexOf(",") + 1);
var newfile = Convert.FromBase64String(data);
var layoutfilename = Guid.NewGuid().ToString() + "_imgage.jpg";
var dataFile = Server.MapPath(#"~/Img/" + layoutfilename);
System.IO.File.WriteAllBytes(dataFile, newfile);
}
Looking at Cropit's source code, here's the relevant bit of code to the output data size:
Cropit.prototype.getCroppedImageData = function(exportOptions) {
var canvas, canvasContext, croppedSize, exportDefaults, exportZoom;
if (!this.imageSrc) {
return null;
}
exportDefaults = {
type: "image/png",
quality: .75,
originalSize: false,
fillBg: "#fff"
};
exportOptions = $.extend({}, exportDefaults, exportOptions);
This is the beginning of the function eventually called by cropit('export').
What's happened here is your input data's compression yields a smaller input than what a quality (7, 8, not sure here) PNG image would output.
You can specify options in the cropit() call - from the plugin's documentation:
$imageCropper.cropit('export', {
type: 'image/jpeg',
quality: .9,
originalSize: true
});
Related
I have an image with base64 url as src. I would like to send this image to the server using an input file (with a form).
So, i need to convert an img tag to an input file.
I am using the plugin Croppie to crop an image. Then, the result is writen in an img tag.
I have tried to convert the img tag into a File. But then i dont know how to convert the file to an input file.
<div>
<label for="img">Image</label><input type="file" name="img" id="img" value=""/>
</div>
<div>
<img id="outImg" />
<input type="file" name="imgtbn" id="imgtbn" value=""/>
</div>
document.getElementById('img').onchange = function (evt) {
var output = document.getElementById('outImg');
output.src = URL.createObjectURL(evt.target.files[0]);
if(this.c!=undefined)
{
this.c.destroy();
}
var el = document.getElementById('outImg');
this.c = new Croppie(el, {
viewport: { width: 300, height: 300 },
boundary: { width: 900, height: 300 },
showZoomer: false,
enableOrientation: true,
update: function (data) {
this.result('base64').then(function(dataImg) {
$('#imgCropped').attr('src', dataImg);
img = document.getElementById('imgCropped');
fetch(img.src)
.then(res => res.blob())
.then(blob => {
file = new File([blob], 'file', blob)
document.getElementById('imgtbn').file = file;
});
})
}
});
};
I would like to have an input file filled with the cropped image.
Thank you for your time.
You can't. Not only can you not use base64 in a file tag, but only an actual file, but you can't even set the value of a file input in Javascript at all. It's a security issue.
But why do you want to? If you've got the file encoded as base64 already, any text input is fine for sending it to the server. I'd probably use a <input type="hidden"> because it doesn't make sense to display the code. And if you want a preview, use an img tag.
As Amunium said, file inputs are read-only.
Saving the base64 image to a hidden input is the best way to do it.
One can empty file input values programmatically, but they will still be submitted; though empty.
There is a barebones explanation on how to get this done in a simple way.
Today I upload a picture using a simple button (id: "imageUpload") to upload a file. Evthg works perfectly. A thumb of the picture is then visible in "thumb1".
I would like to upload a picture also by clicking the div "preview1".
Here is my code with what I tried :
<input type="file" id="imageUpload">
<div class="preview1 slide" onclick="document.getElementById('imageUpload').click();">
<div id="thumb1" class="thumb"></div>
</div>
and the js :
new AjaxUpload('imageUpload', {
action: "upload",
name: 'userfile',
onSubmit : function(file, extension){
do some work..
},
onComplete: function(file, response) {
do some work..
}
});
Result :
When I click on "preview1", a window open to select a file : OKAY
but then the file is not uploaded (no thumb preview), and only the name of the file appear on the right of "imageUpload" :
Any idea ?
If I am understanding you correctly, you are looking to have a picture thumbnail appear on file upload. This might help you
How to generate a thumbnail image after adding an image inside an input type="file" in a form and submitting them both on the same form
Recycled from user: Che-azeh:
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.onloadend = function () {
preview.src = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
preview.src = "";
}
}
<input type="file" onchange="previewFile()"><br>
<img src="" height="200" alt="Image preview...">
For context, I'm trying to create a "click image" file uploader. Initially there is a default image, which I then click. I trigger a file upload, and the user picks an image file they want. Then I will set the image to replace the default (and do other things with it later). Right now, the front end looks something like this:
<div class="right-preview">
<input type="image" src="img/logo.png" height="240px" width="240px" ng-click="uploadImage('right-image')" id="upload-right-image"/>
<input type="file" id="upload-right" style="visibility: hidden">
</div>
When the image is clicked, it triggers an upload action.
$scope.uploadImage = function(side) {
$image = $('#upload-' + side);
$fileInput = $('#upload-right');
$fileInput.change(function(changeEvent) {
var files = changeEvent.target.files;
for(var i = 0; i < files.length; i++) {
file = files[i];
console.log(file);
}
});
$fileInput.trigger('click');
}
When the change event is fired after the user finishes picking their file, I have the changeEvent and I know they've selected their file. Each of the files has some properties (like name and size) but I'm not seeing anything for accessing the raw data so I can set the src on my other element.
Am I just completely missing how to get the image data, or is there a better way to do this? I have no server (right now) to post this to. Perhaps there is a better way to approach this?
This link may be helpful to you - https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
I took one method from that page and added some additional functionality to hide the file upload button and have the image placeholder trigger its click event.
$('#placeholder').click(function() {
$('#img-upload').trigger('click');
});
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
preview.src = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img width="250" height="250" id="placeholder" src="http://place-hold.it/250x250&text='click to upload'">
<input class="hidden" type="file" onchange="previewFile()" id="img-upload">
I'm trying to access a camera and a photo album on a mobile device and get the chosen image. I did that with the code below. My problem is, it generates image data, and I have to transfer that to another page, but because of the size of the generated string, I can't use URL parameters. It shows me the error: [404] Request-URI Too long. How can I pass the information to the other page?
Here is the code: http://jsfiddle.net/8u426/
The JS:
<script>
oFReader = new FileReader();
oFReader.onload = function (oFREvent) {
document.getElementById("fotoImg").src = oFREvent.target.result;
document.getElementById("fotoImg").style.visibility = "visible";
var screenHeight = screen.availHeight;
screenHeight = screenHeight - 220;
document.getElementById("fotoImg").style.height = screenHeight;
document.getElementById("stringImg").innerText = "Data Image: " + oFREvent.target.result;
};
$(function() {
$("input:file").change(function (){
var input = document.querySelector('input[type=file]');
var oFile = input.files[0];
oFReader.readAsDataURL(oFile);
});
});
</script>
Update:
The problem is: if I try to open a new page passing the Data Image string as a parameter in the URL (with "?"). The new page will show the 404 error that I mentioned, because the string is too long.
Try changing your form to
<form id="form1" method="POST" action="[Page2 URL]">
<input id="filePic" type="file" name="image" accept="image/*" capture />
</form>
where [Page2 URL] is the URL for page to receive the image uploaded.
And JavaScript to
oFReader = new FileReader();
oFReader.onload = function (oFREvent) {
var screenHeight = screen.availHeight;
screenHeight = screenHeight - 220;
var img = $('#fotoImg');
img.attr('src', oFREvent.target.result);
img.css( { height : screenHeight, visibility: 'visible' });
$("#stringImg").text( "Data Image: " + oFREvent.target.result);
$('#form1').submit();
};
$(function() {
$("input:file").change(function (){
var oFile = this.files[0];
oFReader.readAsDataURL(oFile);
});
});
I couldn't make work with php (considering that I didn't want to work with php) and html forms (methods get and post)... So I used the jQuery library called "jQuery Storage".
It was easy, on the page that I select the image you shoud use:
$.sessionStorage([key],[value]);
So, was like that:
$.sessionStorage('chosenImg', document.getElementById("photoImg").src);
And in the new page, to get the value, just add in the code:
$.sessionStorage('chosenImg');
Of course, I had to download de .js library from the website and add the line below on both html pages:
<script src="jquery.storage.js"></script>
The only inconvenient it is a little heavy for mobile, but was the only way I found...
That is it! Thanks everyone!
dataimage base64 data image
is it possible to validate file image size with jquery class orjavascript ?
Can i do that ? I made some research but did not reach anything
Thank you
If you want to check image file being uploaded on client side, check HTML5 File API. Here are some samples at:
http://www.html5rocks.com/en/tutorials/file/dndfiles/
You can get file size, find it's type and access binary content.
I was using File API to read EXIF headers from image without uploading image to server.
Here is a source code:
https://gist.github.com/980275/85da4a96a3bb23bae97c3eb7ca777acdea7ed791
Try this:
<input type="file" id="loadfile" />
<input type="button" value="find size" onclick="Size()" />
Script:
function Size() {
if ( $.browser.msie ) {
var a = document.getElementById('loadfile').value;
$('#myImage').attr('src',a);
var imgbytes = document.getElementById('myImage').fileSize;
var imgkbytes = Math.round(parseInt(imgbytes)/1024);
alert(imgkbytes+' KB');
}else {
var fileInput = $("#loadfile")[0];
var imgbytes = fileInput.files[0].fileSize; // Size returned in bytes.
var imgkbytes = Math.round(parseInt(imgbytes)/1024);
alert(imgkbytes+' KB');
}
}