利用Canvas实现图片裁剪

效果图

实现思路

打开图片并将图片绘制到canvas中;

利用canvas的drawImage()函数来裁剪图片;

将canvas转化为Image即可。

HTML代码:

截图

确认截图

打开

CSS代码

CSS代码基本通过javaScript添加

body {

background-color: black;

}

重点JavaScript代码

变量定义、添加各事件按钮、容器等:

let originWidth; // 图片原始宽度

let originHeight; // 图片原始高度

let container = document.getElementById('container');

let imgDiv = document.getElementById('imgDiv'); // 存放mycanvas

let btnDiv = document.getElementById('btnDiv');

let clipImgDiv = document.getElementById('clipImgDiv'); // 显示裁剪所获的图片

let btn1 = document.getElementById('btn1'); // 截图按钮

let btn2 = document.getElementById('btn2'); // 确认截图按钮

let btn3 = document.getElementById('btn3'); // 打开文件按钮

var oRelDiv = document.createElement("div"); // 截图框

var scaleX = 1;// 图片宽度缩放比例(当前实际/原始)

var scaleY = 1; // 图片高度缩放比例(当前实际/原始)

//拖拽与拉伸方法

//拖拽拉伸所需参数

let params = {

left: 0,

top: 0,

width: 0,

height: 0,

currentX: 0,

currentY: 0,

flag: false,

kind: "drag"

};

// CSS样式修改

container.style.display = 'flex';

container.style.flexDirection = 'column';

btnDiv.style.marginBottom = '20px';

btnDiv.style.height = '30px';

imgDiv.style.marginBottom = '20px';

// 创建canvas,用于显示被裁剪图片

var myCanvas = document.createElement('canvas');

myCanvas.setAttribute('id', 'myCanvas');

myCanvas.style.display = 'block';

/*myCanvas.style.position = 'absolute';*/

myCanvas.width = 600;

myCanvas.height = 600;

myCanvas.style.border = "1px solid #d3d3d3";

myCanvas.innerText = '您的浏览器不支持 HTML5 canvas 标签。';

myCanvas.style.zIndex = 'auto';

var ctx = myCanvas.getContext('2d');

// 被裁剪图片

var img = new Image();

img.src = './images/IMG_1550.jpg';

img.setAttribute('id', 'img');

img.width = 600;

img.height = 600;

img.onload = function () {

console.log('onload()执行...');

ctx.drawImage(img, 0, 0, 600, 600);

originWidth = img.naturalWidth;

originHeight = img.naturalHeight;

console.log('图片原始宽度=', originWidth);

console.log('图片原始高度=', originHeight);

};

// 裁剪得到的图片

let clipImg = new Image();

clipImg.src = '';

clipImg.style.height = '100px';

clipImg.style.width = '100px';

clipImg.alt = '裁剪获得图片...';

// input用于打开文件

let fileInput = document.createElement('input');

fileInput.setAttribute('multiple', 'multiple');

fileInput.setAttribute('type', 'file');

fileInput.setAttribute('id', 'fileInput');

/*btnDiv.appendChild(fileInput);*/

imgDiv.appendChild(myCanvas);

/*clipImgDiv.appendChild(clipImg);*/

一些简单的功能函数

// 生成本地图片URL地址

let getObjectURL = function (file) {

let url = null;

if (window.createObjectURL !== undefined) { // basic

url = window.createObjectURL(file);

} else if (window.webkitURL !== undefined) { // webkit or chrome

url = window.webkitURL.createObjectURL(file);

} else if (window.URL !== undefined) { // mozilla(firefox)

url = window.URL.createObjectURL(file);

}

return url;

};

// 获取指定元素DOM

const ID = function (id) {

return document.getElementById(id);

};

//获取相关CSS属性方法

let getCss = function (o, key) {

return o.currentStyle ? o.currentStyle[key] : document.defaultView.getComputedStyle(o, false)[key];

};

打开本地图片

可伸缩截图框实现思路:

截图框由8各控制截图框大小、位置小div组成,鼠标在选中截图框后在拖动鼠标的过程中会根据鼠标位置对截图框进行实时绘制

// 打开本地图片

fileInput.addEventListener('change', function () {

console.log('change()执行...');

img.src = getObjectURL(this.files[0]);

});

btn3.addEventListener("click", function () {

fileInput.click();

});

截图选框的绘制、拖动、大小调整

btn1.addEventListener("click", function () {

var clickFlag = false;

// 获取canvas中图片实际大小

var iCurWidth = img.width;

var iCurHeight = img.height;

console.log('图片当前实际宽度=', iCurWidth);

console.log('图片当前实际高度=', iCurHeight);

// 可调整截图框

oRelDiv.innerHTML = '';

oRelDiv.style.position = "absolute";

oRelDiv.style.width = iCurWidth + "px";

oRelDiv.style.height = iCurHeight + "px";

oRelDiv.style.top = myCanvas.offsetTop + 'px';

console.log('oRelDiv.style.top = ', oRelDiv.style.top);

oRelDiv.id = "cropContainer";

var iOrigWidth = originWidth;

var iOrigHeight = originHeight;

scaleX = iCurWidth / iOrigWidth; // 图片宽度缩放比例(当前实际/原始)

scaleY = iCurHeight / iOrigHeight; // 图片高度缩放比例(当前实际/原始)

console.log('图片横向(宽度)缩放比=', scaleX);

console.log('图片纵向(高度)缩放比=', scaleY);

// 将oRelDiv插入到myCanvas前

myCanvas.parentNode.insertBefore(oRelDiv, myCanvas);

//初始化坐标与剪裁高宽

var cropW = 80; //截图框默认宽度

var cropH = 80; //截图框默认高度

/*console.log('myCanvas.offsetLeft=', myCanvas.offsetLeft);

console.log('myCanvas.offsetTop=', myCanvas.offsetTop);*/

var posX = myCanvas.width / 2 - cropW / 2; // 截图框左上角x坐标

var posY = myCanvas.height / 2 - cropH / 2; // 截图框左上角y坐标

/*console.log('posX=',posX);

console.log('posY=',posY);*/

oRelDiv.innerHTML = '

' +

'

'

'

'

'

'

'

'

'

'

' +

'' +

'' +

'' +

'';

var startDrag = function (point, target, kind) {

//point是拉伸点,target是被拉伸的目标,其高度及位置会发生改变

//此处的target与上面拖拽的target是同一目标,故其params.left,params.top可以共用,也必须共用

//初始化宽高

params.width = getCss(target, "width");

params.height = getCss(target, "height");

//初始化坐标

if (getCss(target, "left") !== "auto") {

params.left = getCss(target, "left");

}

if (getCss(target, "top") !== "auto") {

params.top = getCss(target, "top");

}

//target是移动对象

point.onmousedown = function (event) {

params.kind = kind;

params.flag = true;

clickFlag = true;

if (!event) {

event = window.event;

}

var e = event;

params.currentX = e.clientX; //鼠标按下时坐标x轴

params.currentY = e.clientY; //鼠标按下时坐标y轴

/*console.log('params.currentX=', params.currentX);

console.log('params.currentY=', params.currentY);*/

//防止IE文字选中,有助于拖拽平滑

point.onselectstart = function () {

return false;

};

document.onmousemove = function (event) {

let e = event ? event : window.event;

clickFlag = false;

if (params.flag) {

var nowX = e.clientX; // 鼠标移动时x坐标

var nowY = e.clientY; // 鼠标移动时y坐标

var disX = nowX - params.currentX; // 鼠标x方向移动距离

var disY = nowY - params.currentY; // 鼠标y方向移动距离

if (params.kind === "n") {

//上拉伸

//高度增加或减小,位置上下移动

target.style.top = parseInt(params.top) + disY + "px";

target.style.height = parseInt(params.height) - disY + "px";

} else if (params.kind === "w") { //左拉伸

target.style.left = parseInt(params.left) + disX + "px";

target.style.width = parseInt(params.width) - disX + "px";

} else if (params.kind === "e") { //右拉伸

target.style.width = parseInt(params.width) + disX + "px";

} else if (params.kind === "s") { //下拉伸

target.style.height = parseInt(params.height) + disY + "px";

} else if (params.kind === "nw") { //左上拉伸

target.style.left = parseInt(params.left) + disX + "px";

target.style.width = parseInt(params.width) - disX + "px";

target.style.top = parseInt(params.top) + disY + "px";

target.style.height = parseInt(params.height) - disY + "px";

} else if (params.kind === "ne") { //右上拉伸

target.style.top = parseInt(params.top) + disY + "px";

target.style.height = parseInt(params.height) - disY + "px";

target.style.width = parseInt(params.width) + disX + "px";

} else if (params.kind === "sw") { //左下拉伸

target.style.left = parseInt(params.left) + disX + "px";

target.style.width = parseInt(params.width) - disX + "px";

target.style.height = parseInt(params.height) + disY + "px";

} else if (params.kind === "se") { //右下拉伸

target.style.width = parseInt(params.width) + disX + "px";

target.style.height = parseInt(params.height) + disY + "px";

} else { //移动

target.style.left = parseInt(params.left) + disX + "px";

target.style.top = parseInt(params.top) + disY + "px";

}

}

document.onmouseup = function () {

params.flag = false;

if (getCss(target, "left") !== "auto") {

params.left = getCss(target, "left");

}

if (getCss(target, "top") !== "auto") {

params.top = getCss(target, "top");

}

params.width = getCss(target, "width");

params.height = getCss(target, "height");

/*console.log('params.width=', params.width);

console.log('params.height', params.width);*/

//给隐藏文本框赋值

posX = parseInt(target.style.left);

posY = parseInt(target.style.top);

cropW = parseInt(target.style.width);

cropH = parseInt(target.style.height);

if (posX < 0) {

posX = 0;

}

if (posY < 0) {

posY = 0;

}

if ((posX + cropW) > iCurWidth) {

cropW = iCurWidth - posX;

}

if ((posY + cropH) > iCurHeight) {

cropH = iCurHeight - posY;

}

//赋值

ID("cropPosX").value = posX;

ID("cropPosY").value = posY;

ID("cropImageWidth").value = parseInt(ID("zxxCropBox").style.width);

ID("cropImageHeight").value = parseInt(ID("zxxCropBox").style.height);

/*console.log('posX=',posX);

console.log('posY=',posY);*/

};

}

};

};

//绑定拖拽

startDrag(ID("zxxDragBg"), ID("zxxCropBox"), "drag");

//绑定拉伸

startDrag(ID("dragLeftTop"), ID("zxxCropBox"), "nw");

startDrag(ID("dragLeftBot"), ID("zxxCropBox"), "sw");

startDrag(ID("dragRightTop"), ID("zxxCropBox"), "ne");

startDrag(ID("dragRightBot"), ID("zxxCropBox"), "se");

startDrag(ID("dragTopCenter"), ID("zxxCropBox"), "n");

startDrag(ID("dragBotCenter"), ID("zxxCropBox"), "s");

startDrag(ID("dragRightCenter"), ID("zxxCropBox"), "e");

startDrag(ID("dragLeftCenter"), ID("zxxCropBox"), "w");

//图片不能被选中,目的在于使拖拽顺滑

ID("myCanvas").onselectstart = function () {

return false;

};

img.onselectstart = function () {

return false;

};

});

所获截图绘制

function cropImage(img, cropPosX, cropPosY, width, height) {

/*var cropContainer = ID("cropContainer");

cropContainer.parentNode.removeChild(cropContainer);*/

/*ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);*/

//sx,sy 是相对于图片的坐标。巨坑

var newCanvas = document.createElement('canvas');

newCanvas.setAttribute('id', 'newCanvas');

newCanvas.width = width * scaleX;

newCanvas.height = height * scaleY;

newCanvas.style.border = "1px solid #d3d3d3";

var newCtx = newCanvas.getContext('2d');

clipImgDiv.appendChild(newCanvas);

newCtx.drawImage(img, cropPosX, cropPosY, width, height, 0, 0, width * scaleX, height * scaleY);

// canvas转化为图片

var newImage = new Image();

newImage.src = newCanvas.toDataURL("image/png");

newImage.style.marginLeft = '5px';

clipImgDiv.appendChild(newImage);

oRelDiv.innerHTML = '';

}

确认截图

// 确认截图

btn2.addEventListener("click", function () {

console.log("clipend......");

var x = document.getElementById("cropPosX").value;

var y = document.getElementById("cropPosY").value;

var w = document.getElementById("cropImageWidth").value;

var h = document.getElementById("cropImageHeight").value;

console.log('cropImage(img,', x, ',', y, ',', parseInt(w), ',', parseInt(h), ')');

cropImage(img, x / scaleX, y / scaleY, parseInt(w) / scaleX, parseInt(h) / scaleY);

});

我是Cloudy,年轻的前端攻城狮一枚,爱专研,爱技术,爱分享。

个人笔记,整理不易,感谢阅读、点赞和收藏。

文章有任何问题欢迎大家指出,也欢迎大家一起交流前端各种问题!

canva画图 图片居中裁剪_Canvas裁剪图片(截选框可拖拽)相关推荐

  1. Java | 将文字生成在空白图片居中位置(根据图片大小,自动调节文字大小)

    Java | 将文字生成在空白图片居中位置(根据图片大小,自动调节文字大小) 话不多说,直接上代码.(大家可以自己根据需要设置图片大小,不过图片过小时,字体会变模糊,尽量设置图片大一点,600~100 ...

  2. css 图片居中放大,不同比例图片居中缩放显示的三种方法

    效果 方法一动态给img标签src属性赋值来达到传入不同比例的图片时始终等比例缩放显示,兼容性最好 HTML代码 复制代码 CSS代码 .img-box{ /*限定图片盒子宽高*/ width:500 ...

  3. html悬浮的图片居中,HTML/CSS:图片居中(水平居中和垂直居中)

    css图片水平居中 1.利用margin: 0 auto实现图片水平居中 利用margin: 0 auto实现图片居中就是在图片上加上css样式margin: 0 auto 如下: 2.利用文本的水平 ...

  4. 在html如何让图片居中 css,CSS怎么让图片居中?如何让图片居中显示

    众所周知,HTML 和 CSS 结合后功能强大,可以做出千变万化的样式,那么你知道如何用 CSS 让图片居中显示吗?本篇文章告诉你 一.display:table-cell HTML 代码如下: CS ...

  5. html怎么把页面和图片居中,css怎么让图片居中?

    在前端页面的开发中,图片的显示方法有两种,分别为:img标签显示图片,background属性设置为背景图片显示.那么我们如何使用css设置图片居中呢? css设置背景图片居中: 1.设置背景图片居中 ...

  6. html图片怎么中心对齐,css图片居中(css怎么让图片水平居中对齐)

    css图片居中 css图片居平分css图片水平居中和笔直居中两种状况,有时候还需要图片同时水平笔直居中,下面分几种居中状况别离介绍. css图片水平居中 运用margin:0auto完成图片水平居中 ...

  7. 图片上传组件_博客必备功能,拖拽上传图片!

    公众号关注 "GitHub 热门" 设为 "星标",带你了解技术圈内热门新鲜事! 现在很多小伙伴都在搭建自己的博客,把自己的一些心得和经验都写在博客上面给一些新 ...

  8. H5实现多图片预览上传,可点击可拖拽控件介绍

    在做图片上传时发现一个蛮好用的控件,支持多张图片同时上传,可以点击选择图片,也可以将图片拖拽到上传框直接上传,方便,好用,接口也简单,基本可以直接放到项目里使用. 先看看他的样式: 选择图片后: $( ...

  9. 图片多选上传拖拽切换位置

    html文件 <!DOCTYPE html> <html> <head>     <meta charset="UTF-8">   ...

最新文章

  1. action_mailer_basics
  2. break 与 continue
  3. 开源车牌识别项目,OpenALPR
  4. Django模版(一)
  5. RMI强制Full GC每小时运行一次
  6. HW 静态路由实现PC间互通
  7. 树莓派安装qq linux,在树莓派上安装Ubuntu Core
  8. CH32F103C8T6核心板三种程序下载方式简介
  9. sqlmap DVWA脱库
  10. linux ssh密钥验证失败,连接Linux的服务器时使用SSH密钥认证及解决自动断连问题...
  11. Echarts 柱状图配置圆角
  12. defs(defs是什么意思)
  13. c++实现n阶行列式计算
  14. 清除系统垃圾脚本 windows
  15. Unity 面试题汇总(五)性能优化知识点相关
  16. [转载] 白酒基础知识
  17. MiniGUI 特性说明
  18. protel 二极管正负极怎么看
  19. 10分钟教你用 Python 控制键盘和鼠标
  20. 成都java培训,尽在传智播客成都中心

热门文章

  1. css京东购物车静态页面实现
  2. Dubbo服务调用原理
  3. CSS控制鼠标的箭头
  4. CSS添加多个背景图片
  5. SpringBoot初步入门
  6. (仿头条APP项目)4.父类BaseFragment创建,用retrofit和gson获取并解析服务器端数据
  7. 【排序算法】— 手写堆排序
  8. nivicat复制mysql数据库[Err] [Dtf] 1273 - Unknown collation: 'utf8mb4_0900_ai_ci'错误
  9. Apollo分布式配置中心在本地的安装教程
  10. Spring之Bean的配置(二)