Resize and upload files without AJAX - javascript

Edit
It seems that this is most likely not possible because the canvas and the file input are not compatible data types.
The way to do something similar is to send an AJAX request using a "data url". I will look into that in more detail. Since I didn't want to use AJAX I'll try to fake the workflow to be more like a normal submit, i.e. with a refresh at the end.
End edit
I want to resize and upload a file without AJAX, as this is how it is currently being done (without a resized image - taken from a phone/tablet) and it works well in terms of workflow.
Hence after doing a resize I want to be able to make the resized "image" the value of a field, if this is possible.
I am using this library http://gokercebeci.com/dev/canvasresize to do the resizing for me.
I tried setting the data variable in the callback to be the file1 input's value i.e.
$("#file1").val(data);
But this threw an error. I have removed it in the code below, since I was pretty sure that wasn't the way to go about it.
I've copied the entire HTML/JS file below (the "Image Uploading" content was an example of using AJAX to upload the image, I have commented it out because I don't want to do that).
<!DOCTYPE html>
<html>
<head>
<title>Resize and Upload Images</title>
<script type="text/javascript" src="/public/javascripts/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="/public/javascripts/zepto.min.js"></script>
<script type="text/javascript" src="/public/javascripts/jquery.exif.js"></script>
<script type="text/javascript" src="/public/javascripts/jquery.canvasResize.js"></script>
<script type="text/javascript" src="/public/javascripts/binaryajax.js"></script>
<script type="text/javascript" src="/public/javascripts/canvasResize.js"></script>
<script type="text/javascript" src="/public/javascripts/exif.js"></script>
</head>
<body style="margin:48px;">
<div id="devcontainer">
<div id="area">
<h3>canvasResize</h3>
<div>
<form action="/upload" enctype="multipart/form-data" method="POST">
<input name="file1" type="file" id="file1"/>
<input name="file1" type="file"/>
<input name="data1" type="text"/>
<input name="data2" type="text"/>
</form>
<p><span></span></p>
<i></i>
</div>
<script>
$().ready(function() {
$('input[name=file1]').change(function(e) {
var file = e.target.files[0];
// RESET
$('#area p span').css('width', 0 + "%").html('');
$('#area img, #area canvas').remove();
$('#area i').html(JSON.stringify(e.target.files[0]).replace(/,/g, ", <br/>"));
// CANVAS RESIZING
canvasResize(file, {
width: 600,
height: 0,
crop: false,
quality: 80,
callback: function(data, width, height) {
// SHOW AS AN IMAGE
// =================================================
var img = new Image();
img.onload = function() {
$(this).css({
'margin': '10px auto',
'width': width,
'height': height
}).appendTo('#area div');
};
// /SHOW AS AN IMAGE
// =================================================
$(img).attr('src', data);
}
});
});
});
</script>
</div>
<div class="clearfix"></div>
</div>
</body>
</html>
<!--
// IMAGE UPLOADING
// =================================================
// Create a new formdata
var fd = new FormData();
// Add file data
var f = canvasResize('dataURLtoBlob', data);
f.name = file.name;
fd.append($('#area input').attr('name'), f);
var xhr = new XMLHttpRequest();
var loaded = Math.ceil((e.loaded / e.total) * 100);
$('#area p span').css({'width': loaded + "%"}).html(loaded + "%");
}
}, false);
// File uploaded
xhr.addEventListener("load", function(e)
{
var response = JSON.parse(e.target.responseText);
if (response.filename)
{
// Complete
$('#area p span').html('done');
$('#area b').html(response.filename);
$('<img>').attr({
'src': response.filename
}).appendTo($('#area div'));
}
}, false);
// Send data
xhr.send(fd);
}
-->

Create a callback function in the main window. Add an iFrame to the page that will handle file upload. Once your files have been uploaded call the call back function with the file names. Add the files to the canvas.

Related

Can't initialize cropper.js (Uncaught TypeError: image.cropper is not a function at FileReader.oFReader.onload)

I'm using cropper.js and when I try to initialize, i get the error Uncaught TypeError: image.cropper is not a function at FileReader.oFReader.onload. I have copied the code from one last project I did, and in that project it works normally.
I have tried both of cropper and cropper.js and nothing works.
And I inport the cropper to html like this the the head of the document.
<script src="node_modules/jquery/dist/jquery.js"></script>
<script src="node_modules/cropperjs/dist/cropper.js"></script>
<link href="node_modules/cropperjs/dist/cropper.css" rel="stylesheet">
<script src="node_modules/jquery-cropper/dist/jquery-cropper.js"></script>
My form is like this with the other fields in it.
<form action="backend/send.php" method="post">
...(more html with the other fields)
<p>Imagem CabeƧalho:<br>
<label class="form-filebutton">Carregar Imagem
<input type="file" id="imagem" name="imagem" accept="image/png, image/jpeg, image/JPEG, image/jpeg2000, image/jpg, image/gif">
</label>
</p>
...(more html with the other fields)
</form>
The image should appear here.
<div class="div-preview hidden">
<img class="img-preview" id="img-preview">
...(more html with buttons to edit the image)
</div>
Here is what I do to initialize Cropper.
$(function() {
var image = $("#img-preview"); //where the image should appear
//Initialize cropper when image is loaded in the form
$("input:file").change(function() {
$(".div-preview").removeClass("hidden"); //show the elements
var oFReader = new FileReader();
oFReader.readAsDataURL(this.files[0]);
oFReader.onload = function (oFREvent) {
image.cropper("destroy"); //In case I change the image
image.attr("src", this.result);
image.cropper({
aspectRatio: 1 / 1,
viewMode: 1,
toggleDragModeOnDblclick: false,
dragMode: "move",
crop: function(e) {}
});
};
});
...(more jQuery and JavaScript to control the buttons)
});
I'm expecting to open the cropper but I get the error Uncaught TypeError: image.cropper is not a function at FileReader.oFReader.onload in the first cropper (image.cropper("destroy");).
to fix it I just moved the following code to the body of my page.
<script src="node_modules/cropperjs/dist/cropper.js"></script>
<script src="node_modules/jquery-cropper/dist/jquery-cropper.js"></script>

Getting text from file using FileReader on Load

So, I've been working on a page that uses only local files (server is not an option, unfortunately. Not even a localhost. The struggle is real.) and I've come to a situation where I need to grab text from a .csv file and populate it to the page. I have this bit of code that works, but I need to have a file set within the function when a button is pressed. Looking up the file manually isn't an option (to visualize what I'm doing, I'm making a mock database file in the most annoying way possible (because I have to, not because I want to)).
In the page I would have something like:
<button id="myButton" onclick="getText()"></button>
<script>
var myFile = "dataset.csv";
...
</script>
The following bit of code works (in regards to having it pull the data from the csv file), but, as I said, I need to pull the text from the file when a button is pressed and just have the file name set in the script, not pulling it up manually.
<!DOCTYPE html>
<html>
<body>
<input type="file" id="fileinput" />
<div id="outputdiv"></div>
<script type="text/javascript">
function readSingleFile(evt) {
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
var splited = contents.split(/\r\n|\n|\r|,/g);
for (i=0; i<splited.length; i++){
document.getElementById("outputdiv").innerHTML = document.getElementById("outputdiv").innerHTML + splited[i] + "<br>";
}
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
}
document.getElementById('fileinput').addEventListener('change', readSingleFile, false);
</script>
</body>
</html>
From what I can tell from the API, I would need to set the file attributes to a blob in order to pass it to FileReader. How I can do this without using an input box, I have no idea. There's also a 50% chance that I am completely wrong about this since I obviously don't know how to get this done.
If someone could show me how to achieve this with regards to what I'm looking for, it would be very much appreciated. I'm absolutely stumped.
Thank you.
Note: CORS restrictons will prevent this from working in most browsers. You can use FireFox Developer Edition, which disables CORS validation.
You can use an XMLHttpRequest to load a local file:
<!DOCTYPE html>
<html>
<body>
<button onclick="readSingleFile()">Click Me</button>
<div id="outputdiv"></div>
<script type="text/javascript">
function readSingleFile() {
let xhr = new XMLHttpRequest();
let url = "relative/path/to/file.txt;
if (!url) return;
xhr.onload = dataLoaded;
xhr.onerror = _ => "There was an error loading the file.";
xhr.overrideMimeType("text/plain");
xhr.open("GET",url);
xhr.send();
}
function dataLoaded(e){
var contents = e.target.responseText;
var splited = contents.split(/\r\n|\n|\r|,/g);
for (i=0; i<splited.length; i++){
document.getElementById("outputdiv").innerHTML = document.getElementById("outputdiv").innerHTML + splited[i] + "<br>";
}
</script>
</body>
</html>

How to resize an image on preview (no database)

I have script to preview input type=file (image), and generate it into pdf.
There's no problem for a small size of image. Then when i input with size 6Mb, the preview is OK, but when generate to pdf, its take very long time and finally stopped.
So, I want to resize the image size to 200x240px. But i don't know how to do it, because the script using javascript and I still newbie on it.
Please help how to resize it on my script.
Script:
function previewFile(){
var preview = document.querySelector('img'); //selects the query named img
var file = document.querySelector('input[type=file]').files[0]; //sames as here
var reader = new FileReader();
reader.onloadend = function () {
console.log(reader.result);
//preview.src = reader.result;
$('#gen-template-frame').contents().find('.logo img').attr('src', reader.result);
}
if (file) {
reader.readAsDataURL(file); //reads the data as a URL
} else {
preview.src = "";
}
}
HTML:
<!doctype html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../css/magang/front.css">
</head>
<body>
<div class="corpname" contenteditable>RUMAH SAKIT HARUM</div>
<div class="logosisma"><img src="https://sismadigroup.com/idcard/images/background/logo-id-card.png" width="219" height="70" /></div>
<div class="logo">
<!--<img src="resize/resize.php?src=https://sismadigroup.com/idcard/templates/images/avatar/3.jpg&scale=10&q=100">-->
<img src="https://sismadigroup.com/idcard/templates/images/avatar/3.jpg" width="200" height="240" />
</div>
<div class="name highlight" contenteditable>Maesyaroh</div>
<div class="position" contenteditable>Siswa Magang</div>
<div class="nik" contenteditable>SM-0035</div>
<div class="BBP">BENAR BAIK PANTAS</div>
<div class="BBPPoint" style="left:135px;"> . </div>
<div class="BBPPoint" style="left:203px;"> . </div>
</body>
</html>
Edit: PHP for PDF generation:
$frontPage = resolveDependency(stripslashes( $_POST[ "html" ] ));
$backPage = resolveDependency(stripslashes( $_POST[ "html2" ]) );
$frontPageCSS = getCSSFromHTML($frontPage);
$backPageCSS = getCSSFromHTML($backPage);
$mpdf = new mPDF('utf-8', array(75, 114.6), 0, '', 0, 0, 0, 0, 0, 0);
$mpdf->WriteHTML($frontPageCSS, 1);
$mpdf->WriteHTML($frontPage, 0);
$mpdf->WriteHTML('<pagebreak>', 2);
$mpdf->WriteHTML($backPageCSS, 1);
$mpdf->WriteHTML($backPage, 0);
$mpdf->Output('card.pdf', 'I');
Since you are using PHP to generate the PDF you can resize the image with PHP before using it with mPDF. I don't see in your code how you load the image, so I suppose that you use the Image() function for loading the image from a file (in this example $fileName is the name of the input image, replace it with the variable that you use in your code):
// $fileName is the name of the input image
list($width,$height)=getimagesize($fileName); // size of input image
$tempFileName=tempnam(sys_get_temp_dir(),"img").".png";
$newWidth=200;
$newHeight=240;
$image=imagecreatefrompng($fileName); // load the input image
$newImage=imagecreatetruecolor($newWidth,$newHeight); //create an empty image
imagecopyresampled($newImage,$image,0,0,0,0,$newWidth,$newHeight,$width,$height);
imagepng($newImage,$tempFileName,9); // saving the new image to disk
// here you create the PDF using the image saved in $tempFileName
unlink($tempFileName); // and finally we delete the temporal file
I solved the same problem on front-end, before uploading file. You can visit a link!
import imageSqResizer from './image-square-resizer.js'
let resizer = new imageSqResizer(
'image-input',
300,
(dataUrl) =>
document.getElementById('image-output').src = dataUrl;
);
//Get blob
let formData = new FormData();
formData.append('files[0]', resizer.blob);
//get dataUrl
document.getElementById('image-output').src = resizer.dataUrl;

image upload and crop client side including on old browsers

I am looking for some sort of image uploader and cropper that works mainly client side before it saves to the server.
I have tried a few things but have the issue that most of it is html5 based and I can't seem to find some sort of flash based uploader for the older browsers.
I got slightly lost with the jquery file uploader which I know can be used in the older browsers and the still need to work on a cropping function (but that looks like it will be mostly server side which would be a last resort).
I have also used http://www.script-tutorials.com/html5-image-uploader-with-jcrop/ which sort of works it uploads but when I want to test the crop function it keeps opening up the upload.php file. I will put the code below here :
<!DOCTYPE html >
<html>
<head>
<title>test image uploader</title>
<!--Stylesheets-->
<link href="css/colorbox.css" rel="stylesheet"/>
<link href="css/jquery.Jcrop.min.css" rel="stylesheet"/>
<!-- scripts-->
<script src="js/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/jquery.Jcrop.min.js" type="text/javascript"></script>
<script src="js/script.js" type="text/javascript"></script>
</head>
<body >
<form id="upload_form" enctype="multipart/form-data" method="post" action="upload.php" onsubmit="return checkForm();">
<input type="hidden" id="x1" name="x1" />
<input type="hidden" id="y1" name="y1" />
<input type="hidden" id="x2" name="x2" />
<input type="hidden" id="y2" name="y2" />
<h2>Please select image file</h2>
<div>
<input type="file" name="image_file" id="image_file" onchange="fileSelectHandler();"/>
</div>
<div class="error"></div>
<div class="step2">
<h2>Please select a crop region</h2>
<img id="preview" />
<div class="info">
<label>File size</label><input type="text" id="filesize" name="filesize" />
<label>Type</label><input type="text" id="filetype" name="filetype" />
<label>Image dimension</label><input type="text" id="filedim" name="filedim" />
<label>W</label><input type="text" id="w" name="w" />
<label>H</label><input type="text" id="h" name="h" />
</div>
<input type="submit" value="Upload" />
</div>
</form>
</body>
<script type="text/javascript">
// convert bytes into friendly format
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};
// check for selected crop region
function checkForm() {
if (parseInt($('#w').val())) return true;
$('.error').html('Please select a crop region and then press Upload').show();
return false;
};
// update info by cropping (onChange and onSelect events handler)
function updateInfo(e) {
$('#x1').val(e.x);
$('#y1').val(e.y);
$('#x2').val(e.x2);
$('#y2').val(e.y2);
$('#w').val(e.w);
$('#h').val(e.h);
};
// clear info by cropping (onRelease event handler)
function clearInfo() {
$('.info #w').val('');
$('.info #h').val('');
};
function fileSelectHandler() {
// get selected file
var oFile = $('#image_file')[0].files[0];
// hide all errors
$('.error').hide();
// check for image type (jpg and png are allowed)
var rFilter = /^(image\/jpeg|image\/png)$/i;
if (!rFilter.test(oFile.type)) {
$('.error').html('Please select a valid image file (jpg and png are allowed)').show();
return;
}
// check for file size
if (oFile.size > 250 * 1024) {
$('.error').html('You have selected too big file, please select a one smaller image file').show();
return;
}
// preview element
var oImage = document.getElementById('preview');
// prepare HTML5 FileReader
var oReader = new FileReader();
oReader.onload = function (e) {
// e.target.result contains the DataURL which we can use as a source of the image
oImage.src = e.target.result;
oImage.onload = function () { // onload event handler
// display step 2
$('.step2').fadeIn(500);
// display some basic image info
var sResultFileSize = bytesToSize(oFile.size);
$('#filesize').val(sResultFileSize);
$('#filetype').val(oFile.type);
$('#filedim').val(oImage.naturalWidth + ' x ' + oImage.naturalHeight);
// Create variables (in this scope) to hold the Jcrop API and image size
var jcrop_api, boundx, boundy;
// destroy Jcrop if it is existed
if (typeof jcrop_api != 'undefined')
jcrop_api.destroy();
// initialize Jcrop
$('#preview').Jcrop({
minSize: [100, 100], // min crop size
boxWidth:600,
aspectRatio: 9/6, // keep aspect ratio 1:1
bgFade: true, // use fade effect
bgOpacity: .4, // fade opacity
onChange: updateInfo,
onSelect: updateInfo,
onRelease: clearInfo
}, function () {
// use the Jcrop API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the Jcrop API in the jcrop_api variable
jcrop_api = this;
});
};
};
// read selected file as DataURL
oReader.readAsDataURL(oFile);
}
</script>
</html>
here is the upload.php code :
<?php
/**
*
* HTML5 Image uploader with Jcrop
*
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2012, Script Tutorials
* http://www.script-tutorials.com/
*/
function uploadImageFile() { // Note: GD library is required for this function
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$iWidth = $iHeight = 200; // desired image result dimensions
$iJpgQuality = 90;
if ($_FILES) {
// if no errors and size less than 250kb
if (! $_FILES['image_file']['error'] && $_FILES['image_file']['size'] < 250 * 1024) {
if (is_uploaded_file($_FILES['image_file']['tmp_name'])) {
// new unique filename
$sTempFileName = 'cache/' . md5(time().rand());
// move uploaded file into cache folder
move_uploaded_file($_FILES['image_file']['tmp_name'], $sTempFileName);
// change file permission to 644
#chmod($sTempFileName, 0644);
if (file_exists($sTempFileName) && filesize($sTempFileName) > 0) {
$aSize = getimagesize($sTempFileName); // try to obtain image info
if (!$aSize) {
#unlink($sTempFileName);
return;
}
// check for image type
switch($aSize[2]) {
case IMAGETYPE_JPEG:
$sExt = '.jpg';
// create a new image from file
$vImg = #imagecreatefromjpeg($sTempFileName);
break;
/*case IMAGETYPE_GIF:
$sExt = '.gif';
// create a new image from file
$vImg = #imagecreatefromgif($sTempFileName);
break;*/
case IMAGETYPE_PNG:
$sExt = '.png';
// create a new image from file
$vImg = #imagecreatefrompng($sTempFileName);
break;
default:
#unlink($sTempFileName);
return;
}
// create a new true color image
$vDstImg = #imagecreatetruecolor( $iWidth, $iHeight );
// copy and resize part of an image with resampling
imagecopyresampled($vDstImg, $vImg, 0, 0, (int)$_POST['x1'], (int)$_POST['y1'], $iWidth, $iHeight, (int)$_POST['w'], (int)$_POST['h']);
// define a result image filename
$sResultFileName = $sTempFileName . $sExt;
// output image to file
imagejpeg($vDstImg, $sResultFileName, $iJpgQuality);
#unlink($sTempFileName);
return $sResultFileName;
}
}
}
}
}
}
$sImage = uploadImageFile();
echo '<img src="'.$sImage.'" />';
The other problem with it is I have no fall back option for the older browsers mainly IE8 and 9 because of it only being html5 based.
can anyone please help with any idea's please.

how can i get the height and width of image without page refresh in file tag? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
get image height and width in file tag using javascript
how can i get the height and width of image without page refresh in file tag?
<HTML>
<HEAD>
<TITLE></TITLE>
<script language="javascript">
function getW(){
var theImg = document.getElementById('testimg');
alert(theImg.width);
}
function getH(){
var theImg = document.getElementById('testimg');
alert(theImg.height);
}
</script>
</HEAD>
<BODY>
<input type="file" id="testimg"/>
<input type="button" value="get Width" onclick="getW()"/>
<input type="button" value="get Height" onclick="getH()"/>
</BODY>
</HTML>
i get the image height and width of image using php code, but that time page will be refreshed, without page refresh i get image size but not a height and width....
You can upload file through iframe and after iframe reloaded get image width/height. In modern browsers you can use FileReader API:
<input type="file" id="files" multiple/>
<script type="text/javascript">
function handleFileSelect() {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result, '" title="', theFile.name, '"/>'].join('');
document.body.appendChild(span);
var img = span.getElementsById('img');
img.onload = function() {
alert(img.src, img.offsetWidth, img.offsetHeight);
document.body.removeChild(span);
}
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
There is an excellent post about reading file in javascript.

Categories