js插件---图片裁剪cropImgBox(适合练习编写插件之用)
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、截图
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(适合练习编写插件之用)的更多相关文章
- js插件---图片裁剪photoClip
js插件---图片裁剪photoClip 一.总结 一句话总结:页面裁剪图片得到base64格式的图片数据,然后把这个数据通过ajax上传给服务器,服务器将base64图片数据解析成图片并且保存到服务 ...
- node.js平台下,cropper.js实现图片裁剪预览并转换为base64发送至服务端。
一 .准备工作 1.首先需要先下载cropper,常规使用npm,进入项目路径后执行以下命令: npm install cropper 2. cropper基于jquery,在此不要忘记引入jq,同时 ...
- cropper.js实现图片裁剪预览并转换为base64发送至服务端。
一 .准备工作 1.首先需要先下载cropper,常规使用npm,进入项目路径后执行以下命令: npm install cropper 2. cropper基于jquery,在此不要忘记引入jq,同时 ...
- smartcrop.js智能图片裁剪库
今天将为大家介绍一款近期github上很不错的开源库 – smartcrop.js.它是一款图片处理的智能裁剪库.在很多项目开发中,经常会遇见上传图片的场景,它可能是用户照片信息,也可能是商品图片等. ...
- H5项目 使用Cropper.js 实现图片 裁剪 操作 (APP端)
参考地址: 1.https://www.jianshu.com/p/b252a7cbcf0b 2.https://blog.csdn.net/weixin_38023551/article/detai ...
- 基于cropper.js的图片上传和裁剪
项目中要求图片上传并裁剪的功能,之前也有接触过很多图片裁剪插件,效果体验不是很好,今天推荐一款好用的插件-cropper,超级好用,裁剪功能丰富,满足了各种需求. 功能: 1:点击选择图片,弹出文件夹 ...
- JavaScript图片裁剪
1.jquery 图片裁剪库选择 Jcrop:http://deepliquid.com/content/Jcrop.html imgareaselect:http://odyniec.net/pro ...
- GIF图片裁剪出指定大小的GIF图片
前言 最近在博客后台上传图片的时候,突然发现上传gif图片的时候裁剪图片有问题.既没法裁剪gif指定区域的图片,又没法裁剪指定区域生成一个新的指定大小的gif图.本来想直接去找个裁剪的库直接放上去的, ...
- 【原】jQuery编写插件
分享一下编写设置和获取颜色的插件,首先我将插件的名字命名为jquery.color.js.该插件用来实现以下两个功能1.设置元素的颜色.2.获取元素的颜色. 先在搭建好如下编写插件的框架: ;(fun ...
随机推荐
- BZOJ 2865 字符串识别(后缀数组+线段树)
很容易想到只考虑后缀长度必须为\(max(height[rk[i]],height[rk[i]+1])+1\)(即\([i,i+x-1]\)代表的串只出现过一次)然后我正着做一遍反着做一遍,再取一个\ ...
- Springboot - -web应用开发-Servlets, Filters, listeners
一.Web开发使用 Controller 基本上可以完成大部分需求,但是我们还可能会用到 Servlet. Filter. Listener等等 二.在spring boot中的三种实现方式 方法一: ...
- thttpd 在S3C6410的移植-web服务程序的应用
1. 在VMWare 虚拟机上将arm-linux-gcc 4.3.1配置好:2. 下载thttpd软件包并解压:3. 在thttpd根目录下运行: ./configure:4. ...
- PNG文件结构分析
http://blog.163.com/iwait2012@126/blog/static/16947232820124411174877/ PNG文件结构分析 对于一个PNG文件来说,其文件头总是由 ...
- 7、java封装、继承、聚合组合
1封装:封装的是属性,封:private 装:set.get‘ 可以看做将属性和get/set方法捆绑的过程. 优点:1.防止对封装数据的未经授权的访问,提高安全性.使用者只能通过事先预定好的方法来访 ...
- ListView实现丰富的列表功能
ListView实现丰富的列表功能 1.主布局activity_main.xml <?xml version="1.0" encoding="utf-8" ...
- http --- 从输入URL到页面加载的过程发生了什么?
可以分为这几个大的过程: DNS解析 TCP连接 客户端发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 结束 其中(1)DNS解析可以理解为主寻找这个IP地址的过程,其中如果找 ...
- Reading and writing
A text file is a sequence of characters stored on a permanent medium like a hard drive, flash memory ...
- Busy waiting
In computer systems organization or operating systems, "busy waiting" refers to a process ...
- Chromium Graphics: Compositor Thread Architecture
Compositor Thread Architecture <jamesr, enne, vangelis, nduca> @chromium.org Goals The main re ...