Image Editor Cropper and Camen with Dropzone
2020.11.03 13:14
이미지 업로드 한후, 자르기, 밝기 등을 조절하는 방법이다.
Cropper Url : https://fengyuanchen.github.io/cropper
Camen Url : http://camanjs.com
Dropzone Url : https://www.dropzonejs.com
<link rel="stylesheet" type="text/css" href="{{asset('css/plugins/file-uploaders/dropzone.css')}}">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropper/2.2.4/cropper.min.css" />
<link rel="stylesheet" type="text/css" href="{{asset('css/plugins/extensions/noui-slider.css')}}" />
<style type="text/css">
#dpzWrap {width:100%;}
#newPhoto {max-width:100%;}
#canvasWrap .waITIng{width:2rem;height:2rem;border-width:0.2em;position:absolute;vertical-align:middle;top:48%;left:48%;z-index:100;opacity:1;}
</style>
<div class="form-group" id="dpzWrap">
<label style="margin-left:0px;">PHOTO</label>
<input type="hidden" name="photo" value="{{ $PHOTO }}" />
<input type="hidden" name="id" value="" />
<div class="dropzone dropzone-area" action="{{ route('files.store') }}" enctype="multipart/form-data" id="dpzPhoto">
<div class="dz-message">Drop or Click</div>
</div>
</div>
<script src="{{asset('vendors/js/extensions/dropzone.min.js')}}"></script>
<script src="{{asset('vendors/js/extensions/nouislider.min.js')}}"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/camanjs/4.1.2/caman.full.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/cropper/2.2.4/cropper.min.js"></script>
<script type="text/javascript">
var formData = new FormData();
Dropzone.autoDiscover=false;
Dropzone.options.dpzPhoto={
paramName:"file",
method:"post",
url:"{{ route('files.store') }}",
withCredentials:true,
maxFilesize:50,
maxFiles:1,
acceptedFiles:"image/*",
thumbnailMethod:'contain',
addRemoveLinks:true,
clickable:true,
headers:{'X-CSRF-TOKEN':csToken},
params: {
_token:csToken,
mod:'ChildProfile',
fcode:$('#programSelect').find(':selected').data('code'),
mid:'{{ $child->id }}'
},
removedfile:function(file){
var x=confirm('Do you want to delete?');
if(x){
var fid=file.previewElement.getAttribute("data-fid"),
fname=file.previewElement.getAttribute("data-fname");
if(fid||fname){
var param={fid:fid,fname:fname};
exec_json('{{ route("file.destroy") }}',param,function(resp){
if(resp.error==0){
$('#dpzWrap input[name="photo"]').val('');
$(".dz-hidden-input").prop("disabled",false);
file.previewElement.remove()
}
})
}
}
}
}
jQuery(document).ready(function($){
var dpzPhoto=$("#dpzPhoto").dropzone({
init:function(){
dpzImage=this;
var mockOne={name:'',url:'{{$profilePhoto}}',srl:'{{$child->id}}'};
dpzImage.options.addedfile.call(dpzImage,mockOne);
dpzImage.options.thumbnail.call(dpzImage,mockOne,mockOne.url);
dpzImage.emit("complete",mockOne);
mockOne.previewElement.setAttribute('data-fname',mockOne.url);
dpzImage.disable();
this.on("error",function(resp){
console.log(JSON.stringify(resp))
}),
this.on('removedfile',function(file){
dpzImage.enable()
}),
this.on("success",function(file,resp){
if(resp.filename){
file.previewElement.setAttribute('data-fid',resp.id);
file.previewElement.setAttribute('data-fname',resp.filename);
$('#dpzWrap input[name="fid"]').attr('value',resp.id);
$('#dpzWrap input[name="photo"]').attr('value',resp.filename);
dpzImage.disable();
var code=$('#programSelect').find(':selected').data('code');
if(typeof code!='undefined'){
if($('canvas#newPhoto').length)$('canvas#newPhoto').remove();
if(file.status =='success'){
$('#dpzWrap input[name="photo"]').val(resp.filename);
var image=$('<img/>',{'id':"newPhoto",'src':resp.source}).css({'height':'350px','width':'100%;'});
$('#canvasWrap').append(image);
$('#newPhoto').css('opacity','0.2');
var spinNER=$('#canvasWrap').waiTing();
$('#canvasWrap img').one("load",function(){
startCaman(resp.source);
$('#onPhoto').modal({backdrop:'static',keyboard:false,show:true})
});
}
}else alert("Please select Program First!!")
}
});
}
}).find(".dz-size").remove();
var $modal=$('#onPhoto');
function startCaman(url){
Caman('#newPhoto',function(){
URL.revokeObjectURL(url);
this.render()
});
setTimeout(function(){resetCaman()},50)
}
function startCropper(){
var $canvas=$('#newPhoto');
if($canvas.data('cropper'))$canvas.cropper('destroy');
$canvas.cropper({
aspectRatio:5/7,
autoCropArea:1,
viewMode:3,
responsive:false,
preview:".preview",
crop:function(e){},
built:function(){
$('#newPhoto').css('opacity','1');
$('#canvasWrap').find(".waITIng").remove();
$canvas.cropper('getCroppedCanvas')
}
})
}
function resetCaman(){
Caman("#newPhoto",function(){
this.revert(true);
this.contrast(0).render();
this.brightness(0).render()
});
brightness.noUiSlider.set(0);
brightval.innerHTML=0;contrast.noUiSlider.set(0);
contrastval.innerHTML=0
}
$modal.on('shown.bs.modal',function(){
startCropper();
brightness.noUiSlider.on('change',function(e){
Caman("#newPhoto",function(){
this.revert(true);
this.brightness(parseInt(e)).render(startCropper);
brightval.innerHTML=parseInt(e)
})
});
contrast.noUiSlider.on('change',function(e){
Caman("#newPhoto",function(){
this.revert(true);
this.contrast(parseInt(e)).render(startCropper);
contrastval.innerHTML=parseInt(e)
})
})
}).on('hidden.bs.modal',function(){
var $canvas=$('#newPhoto');
if($canvas.data('cropper')){
$canvas.cropper('destroy')
}
$('#fileinput').prop("value","");
resetCaman()
});
$("#toSave").click(function(){
var spinNER=$(this).waiTing(),cropper=$('#newPhoto').data('cropper');
canvas=cropper.getCroppedCanvas({width:205,height:287});
canvas.toBlob(function(blob){
url=URL.createObjectURL(blob);
var reader=new FileReader();
reader.readAsDataURL(blob);
reader.onloadend=function(){
var base64data=reader.result,
code=$('#programSelect').find(':selected').data('code'),
photo=$('#dpzWrap input[name="photo"]').val(),
fid=$('#dpzWrap input[name="fid"]').val(),
params={name:photo,data:base64data,code:code,photo:photo,mod:'ChildProfile',fid:fid,action:'post',crl:'{{$child->id}}'};
exec_json('/sponsorship/childprofiles/pixie',params,getPHOTO);
spinNER.done(1)
}
})
});
$('#camanReset').on('click',function(){
resetCaman();
brightness.noUiSlider.set(0);
brightval.innerHTML=0;
contrast.noUiSlider.set(0);
contrastval.innerHTML=0
});
var brightness=document.getElementById("brightness"),brightval=document.getElementById("brightness-val");
noUiSlider.create(brightness,{start:0,behaviour:"hover-snap",range:{min:-50,max:50}});
var contrast=document.getElementById("contrast"),contrastval=document.getElementById("contrast-val");
noUiSlider.create(contrast,{start:0,behaviour:"hover-snap",range:{min:-50,max:50}});
});
</script>
<div id="onPhoto" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-body">
<div class="img-container">
<div class="row">
<div class="col-8" id="canvasWrap" style="max-height:380px;max-width:60%;"></div>
<div class="col-4">
<div class="preview"></div>
<div class="form-group" style="text-align:left;margin:0 1rem;">
<label>Brightness : <span id="brightness-val">0</span></label>
<div id="brightness" class="my-1"></div>
</div>
<div class="form-group" style="text-align:left;margin:0 1rem;">
<label>Contrast : <span id="contrast-val">0</span></label>
<div id="contrast" class="my-1"></div>
</div>
<button type="button" class="btn btn-light btn-sm shadow float-right" id="camanReset">Reset</button>
<!--button type="button" class="btn btn-light btn-sm shadow float-right mr-1" id="setCropper">Crop</button-->
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" id="toSave">Save</button>
</div>
</div>
</div>
</div>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropper/2.2.4/cropper.min.css" />
<link rel="stylesheet" type="text/css" href="{{asset('css/plugins/extensions/noui-slider.css')}}" />
<style type="text/css">
#dpzWrap {width:100%;}
#newPhoto {max-width:100%;}
#canvasWrap .waITIng{width:2rem;height:2rem;border-width:0.2em;position:absolute;vertical-align:middle;top:48%;left:48%;z-index:100;opacity:1;}
</style>
<div class="form-group" id="dpzWrap">
<label style="margin-left:0px;">PHOTO</label>
<input type="hidden" name="photo" value="{{ $PHOTO }}" />
<input type="hidden" name="id" value="" />
<div class="dropzone dropzone-area" action="{{ route('files.store') }}" enctype="multipart/form-data" id="dpzPhoto">
<div class="dz-message">Drop or Click</div>
</div>
</div>
<script src="{{asset('vendors/js/extensions/dropzone.min.js')}}"></script>
<script src="{{asset('vendors/js/extensions/nouislider.min.js')}}"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/camanjs/4.1.2/caman.full.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/cropper/2.2.4/cropper.min.js"></script>
<script type="text/javascript">
var formData = new FormData();
Dropzone.autoDiscover=false;
Dropzone.options.dpzPhoto={
paramName:"file",
method:"post",
url:"{{ route('files.store') }}",
withCredentials:true,
maxFilesize:50,
maxFiles:1,
acceptedFiles:"image/*",
thumbnailMethod:'contain',
addRemoveLinks:true,
clickable:true,
headers:{'X-CSRF-TOKEN':csToken},
params: {
_token:csToken,
mod:'ChildProfile',
fcode:$('#programSelect').find(':selected').data('code'),
mid:'{{ $child->id }}'
},
removedfile:function(file){
var x=confirm('Do you want to delete?');
if(x){
var fid=file.previewElement.getAttribute("data-fid"),
fname=file.previewElement.getAttribute("data-fname");
if(fid||fname){
var param={fid:fid,fname:fname};
exec_json('{{ route("file.destroy") }}',param,function(resp){
if(resp.error==0){
$('#dpzWrap input[name="photo"]').val('');
$(".dz-hidden-input").prop("disabled",false);
file.previewElement.remove()
}
})
}
}
}
}
jQuery(document).ready(function($){
var dpzPhoto=$("#dpzPhoto").dropzone({
init:function(){
dpzImage=this;
var mockOne={name:'',url:'{{$profilePhoto}}',srl:'{{$child->id}}'};
dpzImage.options.addedfile.call(dpzImage,mockOne);
dpzImage.options.thumbnail.call(dpzImage,mockOne,mockOne.url);
dpzImage.emit("complete",mockOne);
mockOne.previewElement.setAttribute('data-fname',mockOne.url);
dpzImage.disable();
this.on("error",function(resp){
console.log(JSON.stringify(resp))
}),
this.on('removedfile',function(file){
dpzImage.enable()
}),
this.on("success",function(file,resp){
if(resp.filename){
file.previewElement.setAttribute('data-fid',resp.id);
file.previewElement.setAttribute('data-fname',resp.filename);
$('#dpzWrap input[name="fid"]').attr('value',resp.id);
$('#dpzWrap input[name="photo"]').attr('value',resp.filename);
dpzImage.disable();
var code=$('#programSelect').find(':selected').data('code');
if(typeof code!='undefined'){
if($('canvas#newPhoto').length)$('canvas#newPhoto').remove();
if(file.status =='success'){
$('#dpzWrap input[name="photo"]').val(resp.filename);
var image=$('<img/>',{'id':"newPhoto",'src':resp.source}).css({'height':'350px','width':'100%;'});
$('#canvasWrap').append(image);
$('#newPhoto').css('opacity','0.2');
var spinNER=$('#canvasWrap').waiTing();
$('#canvasWrap img').one("load",function(){
startCaman(resp.source);
$('#onPhoto').modal({backdrop:'static',keyboard:false,show:true})
});
}
}else alert("Please select Program First!!")
}
});
}
}).find(".dz-size").remove();
var $modal=$('#onPhoto');
function startCaman(url){
Caman('#newPhoto',function(){
URL.revokeObjectURL(url);
this.render()
});
setTimeout(function(){resetCaman()},50)
}
function startCropper(){
var $canvas=$('#newPhoto');
if($canvas.data('cropper'))$canvas.cropper('destroy');
$canvas.cropper({
aspectRatio:5/7,
autoCropArea:1,
viewMode:3,
responsive:false,
preview:".preview",
crop:function(e){},
built:function(){
$('#newPhoto').css('opacity','1');
$('#canvasWrap').find(".waITIng").remove();
$canvas.cropper('getCroppedCanvas')
}
})
}
function resetCaman(){
Caman("#newPhoto",function(){
this.revert(true);
this.contrast(0).render();
this.brightness(0).render()
});
brightness.noUiSlider.set(0);
brightval.innerHTML=0;contrast.noUiSlider.set(0);
contrastval.innerHTML=0
}
$modal.on('shown.bs.modal',function(){
startCropper();
brightness.noUiSlider.on('change',function(e){
Caman("#newPhoto",function(){
this.revert(true);
this.brightness(parseInt(e)).render(startCropper);
brightval.innerHTML=parseInt(e)
})
});
contrast.noUiSlider.on('change',function(e){
Caman("#newPhoto",function(){
this.revert(true);
this.contrast(parseInt(e)).render(startCropper);
contrastval.innerHTML=parseInt(e)
})
})
}).on('hidden.bs.modal',function(){
var $canvas=$('#newPhoto');
if($canvas.data('cropper')){
$canvas.cropper('destroy')
}
$('#fileinput').prop("value","");
resetCaman()
});
$("#toSave").click(function(){
var spinNER=$(this).waiTing(),cropper=$('#newPhoto').data('cropper');
canvas=cropper.getCroppedCanvas({width:205,height:287});
canvas.toBlob(function(blob){
url=URL.createObjectURL(blob);
var reader=new FileReader();
reader.readAsDataURL(blob);
reader.onloadend=function(){
var base64data=reader.result,
code=$('#programSelect').find(':selected').data('code'),
photo=$('#dpzWrap input[name="photo"]').val(),
fid=$('#dpzWrap input[name="fid"]').val(),
params={name:photo,data:base64data,code:code,photo:photo,mod:'ChildProfile',fid:fid,action:'post',crl:'{{$child->id}}'};
exec_json('/sponsorship/childprofiles/pixie',params,getPHOTO);
spinNER.done(1)
}
})
});
$('#camanReset').on('click',function(){
resetCaman();
brightness.noUiSlider.set(0);
brightval.innerHTML=0;
contrast.noUiSlider.set(0);
contrastval.innerHTML=0
});
var brightness=document.getElementById("brightness"),brightval=document.getElementById("brightness-val");
noUiSlider.create(brightness,{start:0,behaviour:"hover-snap",range:{min:-50,max:50}});
var contrast=document.getElementById("contrast"),contrastval=document.getElementById("contrast-val");
noUiSlider.create(contrast,{start:0,behaviour:"hover-snap",range:{min:-50,max:50}});
});
</script>
<div id="onPhoto" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-body">
<div class="img-container">
<div class="row">
<div class="col-8" id="canvasWrap" style="max-height:380px;max-width:60%;"></div>
<div class="col-4">
<div class="preview"></div>
<div class="form-group" style="text-align:left;margin:0 1rem;">
<label>Brightness : <span id="brightness-val">0</span></label>
<div id="brightness" class="my-1"></div>
</div>
<div class="form-group" style="text-align:left;margin:0 1rem;">
<label>Contrast : <span id="contrast-val">0</span></label>
<div id="contrast" class="my-1"></div>
</div>
<button type="button" class="btn btn-light btn-sm shadow float-right" id="camanReset">Reset</button>
<!--button type="button" class="btn btn-light btn-sm shadow float-right mr-1" id="setCropper">Crop</button-->
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" id="toSave">Save</button>
</div>
</div>
</div>
</div>