用cropper.js实现图片合成
1.html的头部和尾部分别引入cropper的css和js文件;
<head>
<link rel="stylesheet" href="路径/cropper.min.css">
</head>
<body>
<!-- 背景图片 -->
<div id="page-one">
<img id="page-one-img01" src="路径/bg01.png" alt="" >
</div>
<!-- 导入图片 -->
<div class="page-one-btn-box">
<a href="javascript:void(0);" id="aFile" class="page-one-btn">
<input type="file" name="pic[]" style="width:100%;height:100%;" id="upload-pic" accept="image/*" >
</a>
</div>
<!-- 图片合成界面 -->
<!-- 1.预览区域 -->
<div id="page-two" style="display:none">
<!-- 相对定位 -->
<div class="preview-box">
<!-- 绝对定位 -->
<div class="previw-image-box" >
</div>
<!-- 绝对定位 -->
<div id="clip-image-box">
</div>
</div>
<!-- 2.操作按钮 -->
<div class="btn-wrapper">
<!-- 取消合成 -->
<span id="cancel-upload" class="common-btn"></span>
<!-- 确定合成 -->
<span class="btn-two common-btn" id="merge-image"></span>
</div>
<!--3. cropper.js的固定写法-->
<div class="tailoring-wrapper">
<!-- 用一个块元素(容器)包装图像或画布元素 -->
<div class="box">
<img id="image" src="" style="max-width:100%;">
</div>
<div class="small"></div>
</div>
<!--4.合成图片容器-->
<div>
<div id="merge-image-box">
<img src="" alt="" id="final-merge-image" style="width:100%;height:auto;">
</div>
<div style="text-align:center;display:none;" class="share-introduct-box">
<button id="share-introduct" class="btn btn-default">长按图片保存并分享至朋友圈</button>
</div>
</div>
</div>
<!-- 上传图片缓冲 -->
<div class="my-loading" style="display:none;">
正在导入图片,请稍后。
</div>
</body>
<script src="路径/cropper-all.js"></script>
<script>
</script>
2.如下为原始背景图,中间白色区域放需要合成的图片。
3.下面是具体代码实现
<script>
$(function(){
var orginal_image={
width:550,
height:1000,
inner_width:128,
inner_height:128,
middle_height:240,
middle_top:95,
middle_left:211,
left:211,
top:326
}
var sourceCanvas="";//裁剪的canvas;
var clientWidth=getClientWidth(); //获取设备的宽度
/*
上传文件
**/
$("#upload-pic").change(function(event){
$(".my-loading").show(); //做一个缓冲界面
var files=event.target.files;
console.log(files);
var testImgType=/image\/\w+/;//上传的图片限定为图片
for(var i=0;i<files.length;i++){
if(!testImgType.test(files[i].type)){
alert("请选择图片格式上传");
return false;
}
}
preview_picture(files); //调用预览图片函数
event.target.value="";//清空上传文件,以免后续重新上传时干扰
});
/**
预览图片
*/
function preview_picture(pics){
var r=new FileReader();//利用FileReader获取图片数据
r.readAsDataURL(pics[0]);
r.onload=function(e){
var base_data=e.currentTarget.result;
$(".my-loading").hide();//隐藏缓冲界面
$("#page-one").hide();//隐藏初始页面
$("#page-two").show();//显示合成图片界面
getPreviewSize();//根据预览图片的长宽比例,以当前屏幕宽度为准,设置预览区域的长宽
//如下图所示
$(".tailoring-wrapper").show();//裁剪区域
//由于原始背景图太大,我们取中间一部分图片。方便查看图片裁剪合成效果。
var img_url="路径/middle01.png"
$(".previw-image-box").css({
"background-image":"url("+img_url+")"
})
$("#image").attr("src",base_data);
$(".box").html($("#image"))
getTailoringWrapper(base_data); //进入图片裁剪
//取消合成操作
$("#cancel-upload").on("click",function(){
$("#page-one").show();
$("#page-two").hide();
})
//合成图片操作
$("#merge-image").on("click",function(){
//把两张图合并为一张;
var bg_url="背景图片路径/bg01-2.png";
var inner_url=sourceCanvas.toDataURL("image/jpeg");//将通过cropper.js裁剪的canvas转换成图片
var canvas = document.createElement("canvas");//创建一个canvas
//分小屏幕、中屏幕
var m_client_width=clientWidth;
var show_width=m_client_width*0.6;//canvas显示宽度
var ratio=show_width/(orginal_image.width);
var show_height=ratio*(orginal_image.height);//canvas显示高度
canvas.width=orginal_image.width;//canvas的绘制宽度,一定大于等于原始图片,否则会绘制失真
canvas.height=orginal_image.height;//canvas的绘制高度,一定大于等于原始图片,否则会绘制失真
canvas.setAttribute("style","width:"+show_width+"px;height:"+show_height+"px;")
var context = canvas.getContext("2d");
context.fillStyle = "#fff";
context.fill();
//1.先绘制裁剪图;
var img2=new Image();
img2.src=inner_url;
img2.onload=function(){
//计算中间镂空图片的宽度,和在背景图片中的位置,注意以原背景图为参考,因为canvas绘制的为原背景图并且没有放大,如有放大,就以放大的为准
var inner_image_width=(orginal_image.inner_width);
var inner_image_height=(orginal_image.inner_height);
var start_point_left=(orginal_image.left);
var start_point_top=(orginal_image.top);
context.drawImage(img2,start_point_left,start_point_top,inner_image_width,inner_image_height);
//2.绘制背景图
var img=new Image();
img.src = bg_url;
img.onload=function(){
context.drawImage(img, 0, 0,canvas.width, canvas.height);
var final_base64_url=canvas.toDataURL("image/jpeg");//最终合成的图片链接
$("#final-merge-image").attr("src",final_base64_url)
$(".share-introduct-box").show();
$(".tailoring-wrapper").hide();
window.scrollTo(0,document.body.scrollHeight);//滚动条置
}
}
})
}
}
$(".btn-recover").on("click",function(){
$(".tailoring-wrapper").show();
$(".btn-recover").hide();
})
/**
初始化裁剪插件,裁剪图放入相框,预览
*/
function getTailoringWrapper(base_data){
var clip_ratio=(orginal_image.inner_width)/(orginal_image.inner_height)
var original_img=document.getElementById("image");
var t_cropper=new Cropper(original_img,{
aspectRatio : clip_ratio,// 默认比例
preview : '.previewImg',// 预览视图
guides : false, // 裁剪框的虚线(九宫格)
autoCropArea : 0.8, // 0-1之间的数值,定义自动剪裁区域的大小,默认0.8
movable : false, // 是否允许移动图片
dragCrop : true, // 是否允许移除当前的剪裁框,并通过拖动来新建一个剪裁框区域
movable : true, // 是否允许移动剪裁框
resizable : true, // 是否允许改变裁剪框的大小
zoomable : false, // 是否允许缩放图片大小
mouseWheelZoom : false, // 是否允许通过鼠标滚轮来缩放图片
touchDragZoom : true, // 是否允许通过触摸移动来缩放图片
rotatable : true, // 是否允许旋转图片
viewMode:3,//默认为0,3表示图片填满容器
crop : function(e) {
dealImg(t_cropper);
} ,
});
t_cropper.replace(base_data);
}
function dealImg(t_cropper){
/**
1.获取相框宽度;
2.获取各边框的宽度;左,上,右,下
*/
var $target = $("#clip-image-box");
var d_clientWidth=clientWidth;
var ratio=(d_clientWidth*0.6)/(orginal_image.width)
$target.css({
"left":(orginal_image.middle_left)*ratio,
"top":(orginal_image.middle_top)*ratio,
"width":(orginal_image.inner_width)*ratio,
"height":(orginal_image.inner_height)*ratio
});
//通过cropper.js绘制裁剪图片
sourceCanvas=t_cropper.getCroppedCanvas({
width: (orginal_image.inner_width)*ratio*4,
height:(orginal_image.inner_height)*ratio*4,
maxWidth: 4096,
maxHeight: 4096,
imageSmoothingEnabled: false,
imageSmoothingQuality: 'high',
})
$target.html(sourceCanvas);
}
/**
根据当前设备宽度获取预览框的 宽度
*/
function getPreviewSmallWrapper(){
var preview_wrapper_width=200;//canvas显示的大小
if(clientWidth>336&&clientWidth<536){
preview_wrapper_width=200;
}
if(clientWidth>536){
preview_wrapper_width=250;
}
return preview_wrapper_width
}
//获取屏幕宽度
function getClientWidth(){
var clientWidth=0;
if(document.body.clientWidth&&document.documentElement.clientWidth){
clientWidth = (document.body.clientWidth<=document.documentElement.clientWidth)? document.body.clientWidth:document.documentElement.clientWidth;
}else{
clientWidth = (document.body.clientWidth>=document.documentElement.clientWidth)? document.body.clientWidth:document.documentElement.clientWidth;
}
return clientWidth;
}
//获取屏幕高度
function getClientHeight(){
var clientHeight=0;
if(document.body.clientHeight&&document.documentElement.clientHeight){
clientHeight = (document.body.clientHeight<=document.documentElement.clientHeight)? document.body.clientHeight:document.documentElement.clientHeight;
}else{
clientHeight = (document.body.clientHeight>=document.documentElement.clientHeight)? document.body.clientHeight:document.documentElement.clientHeight;
}
return clientHeight;
}
function getPreviewSize(){
var g_clientWidth=clientWidth;
var ratio=(g_clientWidth*0.6)/(orginal_image.width);
$(".previw-image-box").width(g_clientWidth*0.6);
$(".previw-image-box").height((orginal_image.middle_height)*ratio);
$(".preview-box").width(g_clientWidth*0.6);
$(".preview-box").height((orginal_image.middle_height)*ratio);
}
});
</script>
4.点击合成后的图片
5.主要有几点
一.使用cropper.js获取裁剪的图片
二.准确将裁剪的图片放入对应区域,这个根据原始图片中,镂空区域的上边沿和左边沿与原始图片上边沿与左边沿的距离;在根据当前原始图在显示的宽度计算出其缩小比例,就可以得到镂空区域的目前的大小和距现在原始图上边和左边的距离,就可以做相应的移动
三.裁剪后,合成需要注意,绘制canvas时绘制的大小尽量为原图片的大小或更大,不然图片会有失真的情况,那此时镂空区域图片的绘制位置就需要根据背景图绘制的大小决定。
来源:CSDN
作者:弦月-hill
链接:https://blog.csdn.net/gongxuanyue/article/details/103457632