I am trying to crop image and send the cropped data to server side. I am using imgareaselect plugin. I get the coordinates of selection but could not crop the image. All the solutions available on internet is to preview cropped image using css. But how can I get the cropped data? No need of preview the cropped image. My code is
cropw = $('#cropimg').imgAreaSelect({
maxWidth: 300, maxHeight: 300,
aspectRatio: '1:1',
instance: true,
handles: true,
onSelectEnd: function (img, selection) {
x1 = selection.x1;
y1 = selection.y1;
x2 = selection.x2;
y2 = selection.y2;
}
});
Hey #Shahbaz I was trying out a solution for you using cropper.js.
This is what you can do
Download cropper.js from here
//link the js files
<head>
<script src="jquery.js"></script> // optional
<link href="cropper.min.css" rel="stylesheet">
<script src="cropper.min.js"></script>
</head>
Body
<input type="file" name="image" id="image" onchange="readURL(this);"/>
<div class="image_container">
<img id="blah" src="#" alt="your image" />
</div>
<div id="cropped_result"></div> // Cropped image to display (only if u want)
<button id="crop_button">Crop</button> // Will trigger crop event
Javascript
<script type="text/javascript" defer>
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah').attr('src', e.target.result)
};
reader.readAsDataURL(input.files[0]);
setTimeout(initCropper, 1000);
}
}
function initCropper(){
var image = document.getElementById('blah');
var cropper = new Cropper(image, {
aspectRatio: 1 / 1,
crop: function(e) {
console.log(e.detail.x);
console.log(e.detail.y);
}
});
// On crop button clicked
document.getElementById('crop_button').addEventListener('click', function(){
var imgurl = cropper.getCroppedCanvas().toDataURL();
var img = document.createElement("img");
img.src = imgurl;
document.getElementById("cropped_result").appendChild(img);
/* ---------------- SEND IMAGE TO THE SERVER-------------------------
cropper.getCroppedCanvas().toBlob(function (blob) {
var formData = new FormData();
formData.append('croppedImage', blob);
// Use `jQuery.ajax` method
$.ajax('/path/to/upload', {
method: "POST",
data: formData,
processData: false,
contentType: false,
success: function () {
console.log('Upload success');
},
error: function () {
console.log('Upload error');
}
});
});
----------------------------------------------------*/
})
}
</script>
Hope this helps. Thanks.
Added this one based on the accepted answer, In case anyone is using the jquery wrapper for cropper
let ICropper = (function($) {
let $cropperCanvasImage = $('#cropper-canvas-image');
return {
readUrl,
cropImage
}
function readUrl(input) {
if (input.files && input.files[0]) {
let reader = new FileReader();
reader.onload = function(e) {
$cropperCanvasImage.attr('src', e.target.result)
};
reader.readAsDataURL(input.files[0]);
setTimeout(initCropper, 1000);
}
}
function initCropper() {
$cropperCanvasImage.cropper({
aspectRatio: 1 / 1
});
}
function cropImage() {
let imgUrl = $cropperCanvasImage.data('cropper').getCroppedCanvas().toDataURL();
let img = document.createElement("img");
img.src = imgUrl;
$("#cropped-result").append(img);
}
})(jQuery)
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.1/cropper.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script name="jquery-croper-script">
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(require("jquery"),require("cropperjs")):"function"==typeof define&&define.amd?define(["jquery","cropperjs"],r):r(e.jQuery,e.Cropper)}(this,function(c,s){"use strict";if(c=c&&c.hasOwnProperty("default")?c.default:c,s=s&&s.hasOwnProperty("default")?s.default:s,c.fn){var e=c.fn.cropper,d="cropper";c.fn.cropper=function(p){for(var e=arguments.length,a=Array(1<e?e-1:0),r=1;r<e;r++)a[r-1]=arguments[r];var u=void 0;return this.each(function(e,r){var t=c(r),n="destroy"===p,o=t.data(d);if(!o){if(n)return;var f=c.extend({},t.data(),c.isPlainObject(p)&&p);o=new s(r,f),t.data(d,o)}if("string"==typeof p){var i=o[p];c.isFunction(i)&&((u=i.apply(o,a))===o&&(u=void 0),n&&t.removeData(d))}}),void 0!==u?u:this},c.fn.cropper.Constructor=s,c.fn.cropper.setDefaults=s.setDefaults,c.fn.cropper.noConflict=function(){return c.fn.cropper=e,this}}});
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.1/cropper.min.css" />
<input type="file" name="source-image" id="sourceImage" onchange="ICropper.readUrl(this);" />
<div class="image-container">
<img id="cropper-canvas-image" src="#" alt="your image" />
</div>
<div id="cropped-result"></div>
<button onclick="ICropper.cropImage(this)">Crop</button>
Did you try using a crop plugin for Jquery, like:
https://fengyuanchen.github.io/cropper/
You have to import the scripts in your page:
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$targ_w = $targ_h = 150;
$jpeg_quality = 90;
$src = 'demo_files/pool.jpg';
$img_r = imagecreatefromjpeg($src);
$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );
imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
$targ_w,$targ_h,$_POST['w'],$_POST['h']);
header('Content-type: image/jpeg');
imagejpeg($dst_r,null,$jpeg_quality);
exit;
}
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://deepliquid.com/Jcrop/js/jquery.Jcrop.min.js"></script>
<script src="../js/jquery.Jcrop.js"></script>
<link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
<link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
<script language="Javascript">
$(function(){
$('#cropbox').Jcrop({
aspectRatio: 1,
onSelect: updateCoords
});
});
function updateCoords(c)
{
$('#x').val(c.x);
$('#y').val(c.y);
$('#w').val(c.w);
$('#h').val(c.h);
};
function checkCoords()
{
if (parseInt($('#w').val())) return true;
alert('Selecione a área para recorte.');
return false;
};
</script>
</head>
<body>
<div id="outer">
<div class="jcExample">
<div class="article">
<h1>Crop jQuery</h1>
<img src="demo_files/pool.jpg" id="cropbox" />
<form action="crop.php" method="post" onsubmit="return checkCoords();">
<input type="hidden" id="x" name="x" />
<input type="hidden" id="y" name="y" />
<input type="hidden" id="w" name="w" />
<input type="hidden" id="h" name="h" />
<input type="submit" value="Crop Image" />
</form>
</div>
</div>
</div>
</body>
</html>
Related
I want to do the following: after an user uploads 2 pictures I want to log a message that the process was completed so I can do something else afterwards. Here is a fiddle: https://jsfiddle.net/al21al/ms3ogck2/8/
My html is here:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="container-fluid slide2-img">
<p>Click on the "Choose file" button to upload a picture:</p>
<div class="uploadbuttons">
<form class="" action="/action_page.php">
<input type="file" id="picture1">
<div id="appendimg1"></div>
</form>
<form class="" action="/action_page.php">
<input type="file" id="picture2">
<div id="appendimg2"></div>
</form>
</div>
</div>
</body>
</html>
My js:
function doImage1() {
var image1, imgId1;
const fileSelector1 = document.getElementById('picture1'); //get first input
fileSelector1.addEventListener('change', function() { //read the image
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function(e) { //call function to create img and append it
image1 = '<img src="' + e.target.result + '" style="width:200px;height:auto;" id="' + 'image1-morph">';
$("#appendimg1").empty().append(image1);
imgId1 = image1.split('id="').pop().replace('">', '');
console.log('1st img id', imgId1);
};
reader.readAsDataURL(this.files[0]);
}
});
}
function doImage2() {
var image2, imgId2;
const fileSelector2 = document.getElementById('picture2'); //get 2nd input
fileSelector2.addEventListener('change', function() { //read the image
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function(e) { //call function to create img and append it
image2 = '<img src="' + e.target.result + '" style="width:200px;height:auto;" id="' + 'image2-morph">';
$("#appendimg2").empty().append(image2);
imgId2 = image2.split('id="').pop().replace('">', '');
console.log('2nd img id', imgId2);
};
reader.readAsDataURL(this.files[0]);
}
});
}
doImage1();
doImage2();
// how to wait till both images have been uploaded and then execute other code?
alert('both images have been uploaded');
// other code (...)
CSS:
.slide2-img form {
float: left;
}
Now it alerts me before both pictures have been uploaded (the alert shows right after the page render). I've been trying to use async await but to no avail. Could somebody help me please?
I suggest DRY - Don't Repeat Yourself
Here I count the number of images in the div and delegate the change from that div
$(".uploadbuttons").on("change", function(e) {
const tgt = e.target;
if (tgt.type !== "file") return;
if (!tgt.files || !tgt.files[0]) return
const reader = new FileReader();
const idx = tgt.id.replace("picture", "");
reader.onload = function(e) {
const image = `<img src="${e.target.result}" style="width:200px;height:auto;"
id="image${idx}-morph">`;
$("#appendimg"+idx).html(image);
console.log('img', idx);
if ($(".uploadbuttons").find("img").length===2) console.log("Both uploaded")
};
reader.readAsDataURL(tgt.files[0]);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="container-fluid slide2-img">
<p>Click on the "Choose file" button to upload a picture:</p>
<div class="uploadbuttons">
<form id="uploadForm" action="/action_page.php">
<input type="file" id="picture0">
<div id="appendimg0"></div>
<input type="file" id="picture1">
<div id="appendimg1"></div>
</form>
</div>
</div>
</body>
</html>
I am trying to create a form for uploading an image and displaying a small preview of the image after selecting it. The preview is failing to display.
HTML code:
<label for="">Image</label>
<input type="file" class="form-control" name="image" id="img">
<img src="#" id="imgPreview" alt="">
JS code:
function readURL(input) {
if(input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$("#imgPreview").attr('src', e.target.result).width(100).height(100);
}
reader.readAsDataURL(input.files[0]);
}
$("#img").change(function() {
readURL(this);
});
}
Your change function on #img is never called because it inside your readURL function. You just need to put change function outside and everything good to go.
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$("#imgPreview")
.attr("src", e.target.result)
.width(100)
.height(100);
};
reader.readAsDataURL(input.files[0]);
}
}
$("#img").change(function() {
readURL(this);
});
Working demo here
You need to put change event of #img in the page init.
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script src="http://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<label for="">Image</label>
<input type="file" class="form-control" name="image" id="img">
<img src="#" id="imgPreview" alt="">
<script>
$(function () {
$('#img').change(function () {
readURL(this);
});
})
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$("#imgPreview").attr('src', e.target.result).width(100).height(100);
}
reader.readAsDataURL(input.files[0]);
}
}
</script>
</body>
</html>
I want to use Jquery Croppie Plugin on my site to crop image for my user but I've got this problem the code that i write not show as an example in Croppie Site
Here's my code
HTML code
<input type="file" id="upload" value="Choose a file">
<button class="upload-result">Result</button>
<div class="upload-msg">
Upload a file to start cropping
</div>
<div id="upload-demo"></div>
JS code
$uploadCrop = $('#upload-demo').croppie({
viewport: {
width: 200,
height: 200,
type: 'circle'
},
boundary: {
width: 300,
height: 300
}
});
NB : I have link my site with jquery, croppie.js and croppie.css
Try it, it works for me.
I used PHP to save the image.
<?php
if(isset($_POST['imagebase64'])){
$data = $_POST['imagebase64'];
list($type, $data) = explode(';', $data);
list(, $data) = explode(',', $data);
$data = base64_decode($data);
file_put_contents('image64.png', $data);
}
?>
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="utf-8">
<title>Test</title>
<link href="croppie.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="croppie.js"></script>
<script type="text/javascript">
$( document ).ready(function() {
var $uploadCrop;
function readFile(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$uploadCrop.croppie('bind', {
url: e.target.result
});
$('.upload-demo').addClass('ready');
}
reader.readAsDataURL(input.files[0]);
}
}
$uploadCrop = $('#upload-demo').croppie({
viewport: {
width: 200,
height: 200,
type: 'circle'
},
boundary: {
width: 300,
height: 300
}
});
$('#upload').on('change', function () { readFile(this); });
$('.upload-result').on('click', function (ev) {
$uploadCrop.croppie('result', {
type: 'canvas',
size: 'original'
}).then(function (resp) {
$('#imagebase64').val(resp);
$('#form').submit();
});
});
});
</script>
</head>
<body>
<form action="test-image.php" id="form" method="post">
<input type="file" id="upload" value="Choose a file">
<div id="upload-demo"></div>
<input type="hidden" id="imagebase64" name="imagebase64">
Send
</form>
</body>
</html>
a JSFiddle link
I want to add an image in canvas by using browse button. I tried to do something, I can use browse button but not add an image in canvas.How can I do?
<div style="float:left;"><canvas id="c" width="800" height="800"></canvas></div>
<p onclick="jQuery('#file').trigger('click');">Select a file</p>
<input type="file" id="file" name="file" />
Something like this?
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.3.js"></script>
</head>
<body>
<script>
$(function() {
$('#file-input').change(function(e) {
var file = e.target.files[0],
imageType = /image.*/;
if (!file.type.match(imageType))
return;
var reader = new FileReader();
reader.onload = loadFile;
reader.readAsDataURL(file);
});
function loadFile(e) {
var $img = $('<img>', { src: e.target.result });
var canvas = $('#canvas')[0];
var context = canvas.getContext('2d');
$img.load(function() {
context.drawImage(this, 0, 0);
});
}
});
</script>
<div style="float:bottom"><input type="file" id="file-input"><div>
<div style="float:left">
<canvas id="canvas" width="800px" height="800px"></canvas>
</div>
</body>
</html>
I've search for simple image cropping and i found one, i study all the part and now i want to add some features, this features is selecting an image and display it immediately i got it, but i have a little confusing problem, the problem is after selecting image it doesnt display the original size of image.
INDEX.PHP
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html;charset=utf-8">
<title>Jcrop Dynamic Avatar JS/PHP Demo</title>
<link rel="shortcut icon" href="http://teamtreehouse.com/assets/favicon.ico">
<link rel="icon" href="http://teamtreehouse.com/assets/favicon.ico">
<link rel="stylesheet" type="text/css" href="css/styles.css">
<link rel="stylesheet" type="text/css" href="css/jquery.Jcrop.css">
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Wellfleet">
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/jquery.Jcrop.js"></script>
<script type="text/javascript" src="js/cropsetup.js"></script>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
<!--This is what i add---->
<script>
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('.sep').attr('src', e.target.result);
$('.jcrop-preview').attr('src', e.target.result);
};
reader.readAsDataURL(input.files[0]);
}
}
</script>
<!--END---->
</head>
<body>
<div id="wrapper">
<div class="jc-demo-box">
<header>
<h1><span>Create your profile</span></h1>
</header>
<div id="ew" style="width: 500px; height:500px; background: rgb(102,102,102);">
<img src="" id="target" class="sep" alt="crop image"/> //THIS IS THE IMAGE I WANT TO SHOW THE ORIGINAL SIZE AFTER SELECTING FROM FILES
</div>
<div id="button_upload"><span>Select Image</span>
<input type="file" name="fileToUpload" id="fileToUpload" onchange="readURL(this);">
</div>
<div id="mo">
<div id="preview-pane">
<div class="preview-container">
<div id="ew2"> <img src="" class="jcrop-preview" alt="Preview" /> </div>
</div>
</div>
</div>
<!-- #end #preview-pane -->
<div id="form-container">
<form id="cropimg" name="cropimg" method="post" action="crop.php" target="_blank">
<input type="hidden" id="x" name="x">
<input type="hidden" id="y" name="y">
<input type="hidden" id="w" name="w">
<input type="hidden" id="h" name="h">
<input type="submit" id="submit" value="Crop Image!">
</form>
</div>
<!-- #end #form-container -->
</div>
<!-- #end .jc-demo-box -->
</div>
<!-- #end #wrapper -->
</body>
</html>
CROPSETUP.JS
$(function($){
// Create variables (in this scope) to hold the API and image size
var jcrop_api,
boundx,
boundy,
// Grab some information about the preview pane
$preview = $('#preview-pane'),
$pcnt = $('#preview-pane .preview-container'),
$pimg = $('#preview-pane .preview-container img'),
xsize = $pcnt.width(),
ysize = $pcnt.height();
$('#target').Jcrop({
onChange: updatePreview,
onSelect: updatePreview,
bgOpacity: 0.5,
aspectRatio: xsize / ysize
},function(){
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
jcrop_api = this; // Store the API in the jcrop_api variable
// Move the preview into the jcrop container for css positioning
$preview.appendTo(jcrop_api.ui.holder);
});
function updatePreview(c) {
if (parseInt(c.w) > 0) {
var rx = xsize / c.w;
var ry = ysize / c.h;
$('#x').val(c.x);
$('#y').val(c.y);
$('#w').val(c.w);
$('#h').val(c.h);
$pimg.css({
width: Math.round(rx * boundx) + 'px',
height: Math.round(ry * boundy) + 'px',
marginLeft: '-' + Math.round(rx * c.x) + 'px',
marginTop: '-' + Math.round(ry * c.y) + 'px'
});
}
}
});
**Also how can i save the image after submit? here is the code for submit but i'm failed for getting the image after croping.
CROP.PHP
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$targ_w = $targ_h = 180;
$jpeg_quality = 90;
if(!isset($_POST['x']) || !is_numeric($_POST['x'])) {
die('Please select a crop area.');
}
$src = //This where i want to put the image after scrop but i dont know how
$img_r = imagecreatefromjpeg($src);
$dst_r = ImageCreateTrueColor($targ_w, $targ_h);
imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
$targ_w,$targ_h,$_POST['w'],$_POST['h']);
header('Content-type: image/jpeg');
imagejpeg($dst_r,null,$jpeg_quality); // NULL will output the image directly
exit;
}
?>
Thanks!!!