js插件---图片裁剪cropImgBox(适合练习编写插件之用)

时间:2023-01-16 17:11:11

js插件---图片裁剪cropImgBox(适合练习编写插件之用)

一、总结

一句话总结:无论是灰度还是高对比度的图片,都是先处理canvas的像素,使其变成灰度或者高对比度,然后再用canvas.toDataURL('image/png');输出出来

1、img获取图片来源的两种方式是什么?

a、src直接接图片地址

b、src接图片base64格式数据

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMYAAADGCAYAAACJmedZ42w6ICXmpjvKovOPKYwGVmCsB8xsp+rpF01eCriAy7eYqpTYtCXF8P43revYrfaxf8CrXnKcdq0FW0AAAAASUVORK5CYII=" align="absmiddle" style="width:128px;margin-top:4px;border-radius:128px;box-shadow:0px 0px 12px #7E7E7E;">

2、图片裁剪好的canvas是怎么输出图片数据的?

无论是灰度还是高对比度的图片,都是先处理canvas的像素,使其变成灰度或者高对比度,然后再用canvas.toDataURL('image/png');输出出来

 var arr_result = [], arr = obj.clipType.split('|');

 var context = canvas.getContext("2d");
context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
var imageData = canvas.toDataURL('image/png');
arr_result.push(imageData); var _param = 0, key = '';
if (arr.length > 1 && arr[1] == '1') {
context.clearRect(0, 0, 10000, 10000);
key = 'gray';
var imgToGray = imgTrans(canvas, imageData, key, function () {
_param += 1;
imageData = canvas.toDataURL('image/png');
arr_result.push(imageData);
});
}
if (arr.length > 2 && arr[2] == '1') {
context.clearRect(0, 0, 10000, 10000);
key = 'bright';
var imgToGray = imgTrans(canvas, imageData, key, function () {
_param += 1;
imageData = canvas.toDataURL('image/png');
arr_result.push(imageData);
});
}

二、图片裁剪cropImgBox(适合练习)

百度盘下载地址:

链接:https://pan.baidu.com/s/1_gSUaEX23_b73tqHV0FwFQ 密码:1124

1、截图

js插件---图片裁剪cropImgBox(适合练习编写插件之用)

 

2、代码

index.html

 <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="图片裁剪并设置效果插件,暂时只设置了几种效果,后面会加更多效果,敬请期待...">
<meta name="keywords" content="图片裁剪,crop,Image">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Amaze UI CorpImgBox</title>
<meta name="renderer" content="webkit">
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link href="amazeui.css" rel="stylesheet" />
<link href="amazeui.cropimgbox.min.css" rel="stylesheet" />
<script type="text/javascript" src="jquery.min.js"></script>
<script src="cropimgbox.js"></script>
<script type="text/javascript">
(function ($) {
$(function () {
var options =
{
thumbBox: '.cropimgbox-thumbBox',
spinner: '.cropimgbox-spinner',
imgSrc: ''
}
var cropper = $('.cropimgbox-imageBox').cropimgbox(options);
var img = ""; $(document).on('change', '#upload-file', function () {
var reader = new FileReader();
reader.onload = function (e) {
options.imgSrc = e.target.result;
cropper = $('.cropimgbox-imageBox').cropimgbox(options);
getImg();
}
reader.readAsDataURL(this.files[0]);
this.files.length = 0;
})
.on('mouseup','.cropimgbox-imageBox', function () {
getImg();
})
.on('click','#btnZoomIn', function () {
cropper.zoomIn();
cropper.getBlob
})
.on('click','#btnZoomOut', function () {
cropper.zoomOut();
}) function getImg() {
cropper.getDataURL(function (imgs) {
$('.cropimgbox-cropped').html('');
$('.cropimgbox-cropped').append('<img src="' + imgs[0] + '" align="absmiddle" style="width:128px;margin-top:4px;border-radius:128px;box-shadow:0px 0px 12px #7E7E7E;"><p>原图</p>');
$('.cropimgbox-cropped').append('<img src="' + imgs[1] + '" align="absmiddle" style="width:128px;margin-top:4px;border-radius:128px;box-shadow:0px 0px 12px #7E7E7E;"><p>灰化</p>');
$('.cropimgbox-cropped').append('<img src="' + imgs[2] + '" align="absmiddle" style="width:128px;margin-top:4px;border-radius:128px;box-shadow:0px 0px 12px #7E7E7E;"><p>高亮高对比</p>');
});
}
})
})(jQuery);
</script>
</head>
<body>
<div class="cropimgbox">
<div class="cropimgbox-imageBox">
<div class="cropimgbox-thumbBox"></div>
<div class="cropimgbox-spinner" style="display: none"></div>
</div> <div class="cropimgbox-action">
<div class="am-btn-group am-btn-group-xs">
<button type="button" id="btnZoomIn" class="am-btn am-btn-default am-btn-xs am-text-secondary"><span class="am-icon-plus"></span> 放大</button>
<button type="button" id="btnZoomOut" class="am-btn am-btn-default am-btn-xs am-text-secondary"><span class="am-icon-minus"></span> 缩小</button>
</div>
<div class="cropimgbox-contentarea">
<a href="javascript:void(0)" class="cropimgbox-upload-img">
<label for="cropimgbox-upload-file">选择图片...</label>
</a>
<input type="file" class="" name="cropimgbox-upload-file" id="upload-file" />
</div>
</div>
<div class="cropimgbox-cropped"></div>
</div>
</body>
</html>

cropimgbox.js

 /*
cropimgbox.js
------------------------------------------------------------
| Note:暂时提供了除原图外的2种效果(灰化、高亮高对比),可通过修改
| cvtColor、brightnessContrast函数在此基础上渐变多种效果。
-------------------------------------------------------------
*********注:基于cropbox修改 https://github.com/hongkhanh/cropbox *************
Version: 1.0.0
Author: lazyperson
QQ: 564981089
Website: https://github.com/lazyperson
*/
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (typeof exports !== 'undefined') {
module.exports = factory(require('jquery'));
} else {
factory(jQuery);
}
}(function ($) {
"use strict";
var cropimgbox = function (options, el) {
options.expandRatio = options.expandRatio || 1.1;
options.narrowRatio = options.narrowRatio || 0.9;
var el = el || $(options.imageBox),
obj =
{
state: {},
ratio: 1,
//clipType:裁剪后得到的效果图类型,1显示,0不显示。表示类型依次为 原图(必须有)|灰白图|高亮对比图
clipType: '1|1|1',
options: options,
imageBox: el,
thumbBox: el.find(options.thumbBox),
spinner: el.find(options.spinner),
image: new Image(),
getDataURL: function (callfun) {
var width = this.thumbBox.width(),
height = this.thumbBox.height(),
canvas = document.createElement("canvas"),
dim = el.css('background-position').split(' '),
size = el.css('background-size').split(' '),
dx = parseInt(dim[0]) - el.width() / 2 + width / 2,
dy = parseInt(dim[1]) - el.height() / 2 + height / 2,
dw = parseInt(size[0]),
dh = parseInt(size[1]),
sh = parseInt(this.image.height),
sw = parseInt(this.image.width); canvas.width = width;
canvas.height = height; var arr_result = [], arr = obj.clipType.split('|'); var context = canvas.getContext("2d");
context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
var imageData = canvas.toDataURL('image/png');
arr_result.push(imageData); var _param = 0, key = '';
if (arr.length > 1 && arr[1] == '1') {
context.clearRect(0, 0, 10000, 10000);
key = 'gray';
var imgToGray = imgTrans(canvas, imageData, key, function () {
_param += 1;
imageData = canvas.toDataURL('image/png');
arr_result.push(imageData);
});
}
if (arr.length > 2 && arr[2] == '1') {
context.clearRect(0, 0, 10000, 10000);
key = 'bright';
var imgToGray = imgTrans(canvas, imageData, key, function () {
_param += 1;
imageData = canvas.toDataURL('image/png');
arr_result.push(imageData);
});
} function imgTrans(iCanvas, url, key, callback) {
var _th = this;
var canvas = iCanvas,
iCtx = canvas.getContext("2d"),
url = url; var imread = function (_image) {
var width = _image.width,
height = _image.height;
iResize(width, height);
iCtx.drawImage(_image, 0, 0);
var imageData = iCtx.getImageData(0, 0, width, height),
tempMat = new Mat(height, width, imageData.data);
imageData = null;
iCtx.clearRect(0, 0, width, height);
return tempMat;
},
iResize = function (_width, _height) {
canvas.width = _width;
canvas.height = _height;
},
RGBA2ImageData = function (_imgMat) {
var width = _imgMat.col,
height = _imgMat.row,
imageData = iCtx.createImageData(width, height);
imageData.data.set(_imgMat.data);
return imageData;
},
render = function (key, callback) {
var img = new Image();
img.onload = function () {
var myMat = imread(img);
if (key == 'gray') {
var newImage = cvtColor(myMat, "CV_RGBA");
var newIamgeData = RGBA2ImageData(newImage);
iCtx.putImageData(newIamgeData, 0, 0);
}
if (key == 'bright') {
var newImage = brightnessContrast(myMat, 50, 50);
var newIamgeData = RGBA2ImageData(newImage);
iCtx.putImageData(newIamgeData, 0, 0);
}
callback();
};
img.src = url;
}; render(key, callback);
} function Mat(_row, _col, _data, _buffer) {
this.row = _row || 0;
this.col = _col || 0;
this.channel = 4;
this.buffer = _buffer || new ArrayBuffer(_row * _col * 4);
this.data = new Uint8ClampedArray(this.buffer);
_data && this.data.set(_data);
this.bytes = 1;
this.type = "CV_RGBA";
} function cvtColor(_src, _code) {
var row = _src.row,
col = _src.col;
if (_src.type && _code === "CV_RGBA") {
var dst = new Mat(row, col),
data = dst.data,
data2 = _src.data;
var pix1, pix2, pix = _src.row * _src.col * 4;
while (pix) {
data[pix -= 4] = data[pix1 = pix + 1] = data[pix2 = pix + 2] = (data2[pix] * 299 + data2[pix1] * 587 + data2[pix2] * 114) / 1000;
data[pix + 3] = data2[pix + 3];
}
} else if (_src.type && _code === "CV_RGBA2GRAY") {
var dst = new Mat(row, col),
data = dst.data,
data2 = _src.data;
var pix = row * col;
while (pix) {
data[--pix] = (data2[4 * pix] * 9798 + data2[4 * pix + 1] * 19235 + data2[4 * pix + 2] * 3736) >> 15;
}
}
return dst;
} var brightnessContrast = function (__src, __brightness, __contrast) {
if (__src.type === "CV_RGBA") {
var sData = __src.data,
width = __src.col,
height = __src.row,
dst = new Mat(height, width);
var dData = dst.data,
brightness = Math.max(-255, Math.min(255, __brightness || 0)),
contrast = Math.max(-255, Math.min(255, __contrast || 0)); var gray = cvtColor(__src, "CV_RGBA2GRAY", 2),
allValue = 0,
gData = gray.data;
var y, x, c; for (y = height; y--;) {
for (x = width; x--;) {
allValue += gData[y * width + x];
}
} var r, g, b, offset, gAverage = (allValue / (height * width)) | 0; for (y = height; y--;) {
for (x = width; x--;) {
offset = (y * width + x) * 4;
dData[offset] = sData[offset] + brightness;
dData[offset + 1] = sData[offset + 1] + brightness;
dData[offset + 2] = sData[offset + 2] + brightness; if (contrast >= 0) {
for (c = 3; c--;) {
if (dData[offset + c] >= gAverage) {
dData[offset + c] = dData[offset + c] + (255 - gAverage) * contrast / 255;
} else {
dData[offset + c] = dData[offset + c] - (gAverage * contrast / 255);
}
}
} else {
dData[offset] = dData[offset] + (dData[offset] - gAverage) * contrast / 255;
dData[offset + 1] = dData[offset + 1] + (dData[offset + 1] - gAverage) * contrast / 255;
dData[offset + 2] = dData[offset + 2] + (dData[offset + 2] - gAverage) * contrast / 255;
}
dData[offset + 3] = 255;
}
}
}
return dst;
}; var num = arr.length > 1 && arr[1] == '1' || arr.length > 2 && arr[2] == '1' ? (arr.length > 1 && arr[1] == '1' && arr.length > 2 && arr[2] == '1' ? 2 : 1) : 0;
if (arr.length > 1 && arr[1] == '1' || arr.length > 2 && arr[2] == '1') {
if (_param > 0)
return arr_result;
else {
(function func() {
if (_param >= num) {
_param = 0;
callfun(arr_result);
}
else
setTimeout(func, 500);
})();
}
}
},
getBlob: function (i) {
var imageData = this.getDataURL()[i];
var b64 = imageData.replace('data:image/png;base64,', '');
var binary = atob(b64);
var array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], { type: 'image/png' });
},
zoomIn: function () {
this.ratio *= options.expandRatio;
setBackground();
},
zoomOut: function () {
this.ratio *= options.narrowRatio;
setBackground();
}
},
setBackground = function () {
var w = parseInt(obj.image.width) * obj.ratio;
var h = parseInt(obj.image.height) * obj.ratio; var pw = (el.width() - w) / 2;
var ph = (el.height() - h) / 2;
el.css({
'background-image': 'url(' + obj.image.src + ')',
'background-size': w + 'px ' + h + 'px',
'background-position': pw + 'px ' + ph + 'px',
'background-repeat': 'no-repeat'
});
},
imgMouseDown = function (e) {
e.stopImmediatePropagation(); obj.state.dragable = true;
obj.state.mouseX = e.clientX;
obj.state.mouseY = e.clientY;
},
imgMouseMove = function (e) {
e.stopImmediatePropagation(); if (obj.state.dragable) {
var x = e.clientX - obj.state.mouseX;
var y = e.clientY - obj.state.mouseY; var bg = el.css('background-position').split(' '); var bgX = x + parseInt(bg[0]);
var bgY = y + parseInt(bg[1]); el.css('background-position', bgX + 'px ' + bgY + 'px'); obj.state.mouseX = e.clientX;
obj.state.mouseY = e.clientY;
}
},
imgMouseUp = function (e) {
e.stopImmediatePropagation();
obj.state.dragable = false;
},
zoomImage = function (e) {
e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0 ? obj.ratio *= options.expandRatio : obj.ratio *=options.narrowRatio;
setBackground();
} obj.spinner.show(); obj.image.onload = function () {
obj.spinner.hide();
setBackground();
el.bind('mousedown', imgMouseDown);
el.bind('mousemove', imgMouseMove);
$(window).bind('mouseup', imgMouseUp);
el.bind('mousewheel DOMMouseScroll', zoomImage);
}; obj.image.src = options.imgSrc;
el.on('remove', function () { $(window).unbind('mouseup', imgMouseUp) }); return obj;
}; jQuery.fn.cropimgbox = function (options) {
return new cropimgbox(options, this);
};
}));
 

js插件---图片裁剪cropImgBox(适合练习编写插件之用)的更多相关文章

  1. js插件---图片裁剪photoClip

    js插件---图片裁剪photoClip 一.总结 一句话总结:页面裁剪图片得到base64格式的图片数据,然后把这个数据通过ajax上传给服务器,服务器将base64图片数据解析成图片并且保存到服务 ...

  2. node&period;js平台下,cropper&period;js实现图片裁剪预览并转换为base64发送至服务端。

    一 .准备工作 1.首先需要先下载cropper,常规使用npm,进入项目路径后执行以下命令: npm install cropper 2. cropper基于jquery,在此不要忘记引入jq,同时 ...

  3. cropper&period;js实现图片裁剪预览并转换为base64发送至服务端。

    一 .准备工作 1.首先需要先下载cropper,常规使用npm,进入项目路径后执行以下命令: npm install cropper 2. cropper基于jquery,在此不要忘记引入jq,同时 ...

  4. smartcrop&period;js智能图片裁剪库

    今天将为大家介绍一款近期github上很不错的开源库 – smartcrop.js.它是一款图片处理的智能裁剪库.在很多项目开发中,经常会遇见上传图片的场景,它可能是用户照片信息,也可能是商品图片等. ...

  5. H5项目 使用Cropper&period;js 实现图片 裁剪 操作 &lpar;APP端&rpar;

    参考地址: 1.https://www.jianshu.com/p/b252a7cbcf0b 2.https://blog.csdn.net/weixin_38023551/article/detai ...

  6. 基于cropper&period;js的图片上传和裁剪

    项目中要求图片上传并裁剪的功能,之前也有接触过很多图片裁剪插件,效果体验不是很好,今天推荐一款好用的插件-cropper,超级好用,裁剪功能丰富,满足了各种需求. 功能: 1:点击选择图片,弹出文件夹 ...

  7. JavaScript图片裁剪

    1.jquery 图片裁剪库选择 Jcrop:http://deepliquid.com/content/Jcrop.html imgareaselect:http://odyniec.net/pro ...

  8. GIF图片裁剪出指定大小的GIF图片

    前言 最近在博客后台上传图片的时候,突然发现上传gif图片的时候裁剪图片有问题.既没法裁剪gif指定区域的图片,又没法裁剪指定区域生成一个新的指定大小的gif图.本来想直接去找个裁剪的库直接放上去的, ...

  9. 【原】jQuery编写插件

    分享一下编写设置和获取颜色的插件,首先我将插件的名字命名为jquery.color.js.该插件用来实现以下两个功能1.设置元素的颜色.2.获取元素的颜色. 先在搭建好如下编写插件的框架: ;(fun ...

随机推荐

  1. UNITY实现FLASH中的setTimeout

    setTimeout是一个很方便的DELAY处理方法 if (this.startUpDelay > 0){            StartCoroutine(DelayedStart()); ...

  2. sqlite - java 初学

    进来准备使用一种embedded database,即嵌入式数据库,方便随项目本地存储.目前学习打算是sqlite和H2. document:http://www.runoob.com/sqlite/ ...

  3. Codeforces Zip-line 650D 345Div1D&lpar;LIS&rpar;

    传送门 大意:给出一个序列,求修改一个数过后的最长上升子序列. 思路:可以用主席树在线搞,也可以用树状数组离线搞,明显后者好写得多.我们首先读取所有的询问,然后就把询问绑在给出的位置,然后我们正向做一 ...

  4. &lbrack;CFGym101061G&rsqb; Repeat it(逆元)

    题目链接:http://codeforces.com/gym/101061/problem/G 题意:给一个数字n,让你重复m次,求最后这个数对1e9+7取模的结果. 思路:设数字n长度为k,重复m次 ...

  5. IOS开发之路三(XML解析之KissXML的使用)

    最近再做一个项目需要用到xml的解析.今天查了一些资料自己做了一个小demo.纯OC没有界面.. 在IOS平台上进行XML文档的解析有很多种方法,在SDK里面有自带的解析方法,但是大多情况下都倾向于用 ...

  6. Swift - 多线程实现方式(2) - NSOperation和NSOperationQueue

    1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术: (1)NSThread (2)Cocoa NSOperation(NSOperation和NSOperationQueu ...

  7. haproxy&comma;tomcat&period;apache记录用户真实IP

    Haproxy配置: default加入: option httpclose option forwardfor Tomcat配置: server.xml中添加 prefix="localh ...

  8. tcp config

    $ sudo sysctl net.ipv4.tcp_reordering=1 $ sudo sysctl net.ipv4.tcp_thin_linear_timeouts=1 $ sudo sys ...

  9. issue:ssh自动断开

    使用ssh连接云服务器的时候,几分钟不操作terminal就会卡住,实际上ssh连接已经断开了,感觉很不爽.(可能云服务器供应商在系统中做了设置) 解决办法: step1:vim /etc/ssh/s ...

  10. POJ 2752 Seek the Name&comma; Seek the Fame(next数组运用)

    Seek the Name, Seek the Fame Time Limit: 2000MS        Memory Limit: 65536K Total Submissions: 24000 ...