1、在项目中 安装cropper 组件,并将 cropper
npm install cropperjs
2、image-cropper.html页面
<ion-header>
<div class="closeBtn-container">
<div class="closeBtn_left" (tap)="closePage()">
<span class="fa fa-chevron-left closeBtn"></span>
</div>
<div class="closeBtn_right">
<span>裁剪图片</span>
</div>
</div>
</ion-header>
<ion-content no-padding>
<img [src]="src" *ngIf="src != null" #imgSrc (load)="imageLoaded()">
</ion-content>
<ion-footer no-padding>
<ion-toolbar>
<ion-grid>
<ion-row>
<ion-col>
<button color="secondary" ion-button (click)="confirm()">
确认
</button>
</ion-col>
</ion-row>
</ion-grid>
</ion-toolbar>
</ion-footer>
3、image-cropper.scss
image-cropper-page {
.closeBtn-container{
padding: 4px;
height: 44px;
line-height: 44px;
display: flex;
flex-wrap: nowrap;
color: #ffffff;
align-items: center;
.closeBtn_left,.closeBtn_right{
height: 44px;
line-height: 44px;
width: 30px;
text-align:center;
}
.closeBtn_right{
width: 100%;
}
}
ion-footer.footer {
.toolbar {
background-color: color($colors, secondary);
.title .toolbar-title,
.bar-buttons .bar-button {
color: #fff;
}
.toolbar-background {
background-color: color($colors, secondary);
}
}
.toolbar-content {
text-align: center;
ion-grid {
padding: 0px;
ion-row {
ion-col {
padding: 0px;
button {
height: 30px;
}
}
}
}
}
}
// 图片处理
/*!
* Cropper.js v1.0.0
* https://github.com/fengyuanchen/cropperjs
*
* Copyright (c) 2017 Fengyuan Chen
* Released under the MIT license
*
* Date: 2017-09-03T12:52:44.102Z
*/
.cropper-container {
direction: ltr;
font-size: 0;
line-height: 0;
position: relative;
-ms-touch-action: none;
touch-action: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none
}
.cropper-container img {
/* Avoid margin top issue (Occur only when margin-top <= -height) */
display: block;
height: 100%;
image-orientation: 0deg;
max-height: none !important;
max-width: none !important;
min-height: 0 !important;
min-width: 0 !important;
width: 100%;
}
.cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.cropper-wrap-box {
overflow: hidden;
}
.cropper-drag-box {
background-color: #fff;
opacity: 0;
}
.cropper-modal {
background-color: #000;
opacity: .5;
}
.cropper-view-box {
display: block;
height: 100%;
outline-color: rgba(51, 153, 255, 0.75);
outline: 1px solid #39f;
overflow: hidden;
width: 100%;
}
.cropper-dashed {
border: 0 dashed #eee;
display: block;
opacity: .5;
position: absolute
}
.cropper-dashed.dashed-h {
border-bottom-width: 1px;
border-top-width: 1px;
height: 33.33333%;
left: 0;
top: 33.33333%;
width: 100%;
}
.cropper-dashed.dashed-v {
border-left-width: 1px;
border-right-width: 1px;
height: 100%;
left: 33.33333%;
top: 0;
width: 33.33333%;
}
.cropper-center {
display: block;
height: 0;
left: 50%;
opacity: .75;
position: absolute;
top: 50%;
width: 0
}
.cropper-center:before,
.cropper-center:after {
background-color: #eee;
content: ' ';
display: block;
position: absolute;
}
.cropper-center:before {
height: 1px;
left: -3px;
top: 0;
width: 7px;
}
.cropper-center:after {
height: 7px;
left: 0;
top: -3px;
width: 1px;
}
.cropper-face,
.cropper-line,
.cropper-point {
display: block;
height: 100%;
opacity: .1;
position: absolute;
width: 100%;
}
.cropper-face {
background-color: #fff;
left: 0;
top: 0;
}
.cropper-line {
background-color: #39f
}
.cropper-line.line-e {
cursor: e-resize;
right: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-n {
cursor: n-resize;
height: 5px;
left: 0;
top: -3px;
}
.cropper-line.line-w {
cursor: w-resize;
left: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-s {
bottom: -3px;
cursor: s-resize;
height: 5px;
left: 0;
}
.cropper-point {
background-color: #39f;
height: 5px;
opacity: .75;
width: 5px
}
.cropper-point.point-e {
cursor: e-resize;
margin-top: -3px;
right: -3px;
top: 50%;
}
.cropper-point.point-n {
cursor: n-resize;
left: 50%;
margin-left: -3px;
top: -3px;
}
.cropper-point.point-w {
cursor: w-resize;
left: -3px;
margin-top: -3px;
top: 50%;
}
.cropper-point.point-s {
bottom: -3px;
cursor: s-resize;
left: 50%;
margin-left: -3px;
}
.cropper-point.point-ne {
cursor: ne-resize;
right: -3px;
top: -3px;
}
.cropper-point.point-nw {
cursor: nw-resize;
left: -3px;
top: -3px;
}
.cropper-point.point-sw {
bottom: -3px;
cursor: sw-resize;
left: -3px;
}
.cropper-point.point-se {
bottom: -3px;
cursor: se-resize;
height: 20px;
opacity: 1;
right: -3px;
width: 20px;
}
@media (min-width: 768px) {
.cropper-point.point-se {
height: 15px;
width: 15px
}
}
@media (min-width: 992px) {
.cropper-point.point-se {
height: 10px;
width: 10px
}
}
@media (min-width: 1200px) {
.cropper-point.point-se {
height: 5px;
opacity: .75;
width: 5px
}
}
.cropper-point.point-se:before {
background-color: #39f;
bottom: -50%;
content: ' ';
display: block;
height: 200%;
opacity: 0;
position: absolute;
right: -50%;
width: 200%;
}
.cropper-invisible {
opacity: 0;
}
.cropper-bg {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
}
.cropper-hide {
display: block;
height: 0;
position: absolute;
width: 0;
}
.cropper-hidden {
display: none !important;
}
.cropper-move {
cursor: move;
}
.cropper-crop {
cursor: crosshair;
}
.cropper-disabled .cropper-drag-box,
.cropper-disabled .cropper-face,
.cropper-disabled .cropper-line,
.cropper-disabled .cropper-point {
cursor: not-allowed;
}
}
4、image-cropper.ts
import { Component, ElementRef, ViewChild } from '@angular/core';
import { NavParams, NavController, LoadingController, Loading } from 'ionic-angular';
import Cropper from 'cropperjs';
@Component({
selector: 'image-cropper-page',
templateUrl: 'image-cropper.html'
})
export class ImageCropperPage {
@ViewChild('imgSrc') image: ElementRef;
cropper: any;
src: string;
private ratio: number = 2; // 图片截取的宽高比,宽/高。
private loading: Loading; // 读取组件。
private clicked: boolean = false;// 按钮是否被点击
private callbackFunction: Function; // 操作结束后的回调函数。
constructor(
private nc: NavController,
private navParam: NavParams,
private loadCtrl: LoadingController
) {
if(this.navParam.get('callbackFunction')){
this.callbackFunction = this.navParam.get('callbackFunction');
}
if (this.navParam.get('src')) {
this.src = this.navParam.get('src');
}
if (this.navParam.get('ratio')) {
this.ratio = this.navParam.get('ratio');
}
}
/**
* 图片加载完成
*/
imageLoaded() {
if (this.cropper) {
this.cropper.replace(this.image.nativeElement.src);
}
this.cropper = new Cropper(this.image.nativeElement, {
aspectRatio: this.ratio,
viewMode: 1,
dragMode: 'move',
crop: (e) => { }
});
}
/**
* 完成裁剪
*/
confirm() {
if (!this.clicked) {
this.clicked = true;
this.loading = this.loadCtrl.create({
content: '请等待...',
dismissOnPageChange: true
});
let cropBoxData = this.cropper.getCropBoxData();
let canvasOption = {
imageSmoothingEnabled: false,
imageSmoothingQuality: 'high',
height: cropBoxData.height,
width: cropBoxData.width,
minHeight: cropBoxData.height,
minWidth: cropBoxData.width,
maxWidth:cropBoxData.width,
maxHeight:cropBoxData.height,
fillColor:'#fff'
};
//画一张剪裁的图片。如果没有剪裁,则返回一个绘制整个im的画布
let CroppedCanvas = this.cropper.getCroppedCanvas(canvasOption);
//生成base64url数据
let imageBase64 = CroppedCanvas.toDataURL('image/jpeg', 1);
this.loading.present().then(() => {
this.clicked = false;
let returnMap:ReturnMapEntry = {is_ok:true,result:imageBase64};
this.close(returnMap);
}).catch(() => {
this.clicked = false;
});
} else {
return;
}
}
/**
* 关闭
* @param result 向父级页面组件提供的返回值
*/
close(result) {
if (this.loading) {
this.loading.dismiss();
}
this.nc.pop().then(() => {
if (this.callbackFunction) {
this.callbackFunction(result);
}
}).catch(e => {
console.log(e);
});
}
/**
* 关闭
*/
closePage() {
this.nc.pop();
}
ngOnDestroy() {
if (this.loading) {
this.loading.dismiss();
}
}
}