ionic3 图片裁剪 cropper 全过程

准备

corpper.min.css

cropper.min.js

开始

下载上面两个文件,将文件保存到 src/assets目录下,(只要是你自己项目目录下)

在index.html引入这两个文件

在需要上传图片的html页面点击图片进行更改

<div class="logo"  (click)="submitImg()">
    <img [src]="defaultLogo || photo"/>
</div>

ts文件代码点击图片进行更换图片

import { Component } from '@angular/core';
import {ActionSheetController, Events, IonicPage, NavController, NavParams} from 'ionic-angular';
import {NativeServiceProvider} from "../../../../providers/native-service/native-service";


@IonicPage()
@Component({
  selector: 'change-info',
  templateUrl: 'change.html',
})
export class MyInfoPage {
  public defaultLogo = 'assets/img/my_logo.png';    //默认图片路径
  public photo:any;
  constructor(public navCtrl: NavController,
              public navParams: NavParams,
              public actionSheet:ActionSheetController,
              public nativeService:NativeServiceProvider,
              public events:Events) {
   
  }

  ionViewDidLoad() {
    
  }

  //点击图片
  submitImg(){
    const actionSheet = this.actionSheet.create({
      buttons: [
        {
          text: '拍照', handler: () => {this.TakePicture();}
        }, {
          text: '相册', handler: () => {this.ImageSelect();}
        }, {
          text: '取消', role: 'cancel', handler: () => {}
        }
      ]
    });
    actionSheet.present();
  }
  //拍照
  TakePicture(){
    this.nativeService.showLoading();
    this.nativeService.getPictureByCamera().subscribe((picture)=>{
      if (picture) {
        this.nativeService.hideLoading();
        let imgBaseUrl = 'data:image/jpg;base64,' + picture;
        this.navCtrl.push('CropImagePage', {imageSrc: imgBaseUrl }).then(() => {    //发布订阅到裁剪页面
          this.events.subscribe('crop-image:result', imgBase64Str => {    //imgBase64Str 是裁剪后base64格式的图片
            this.photo = imgBase64Str    //base64格式图片显示
          });
        });
      }
    });
  }
  // 相册
  ImageSelect(){
    this.nativeService.showLoading();
    this.nativeService.getPictureByPhotoLibrary().subscribe((picture)=>{
      if (picture) {
        this.nativeService.hideLoading();
        let imgBaseUrl = 'data:image/jpg;base64,' + picture;
        this.navCtrl.push('CropImagePage', {imageSrc: imgBaseUrl }).then(() => {       //发布订阅到裁剪页面
          this.events.subscribe('crop-image:result', imgBase64Str => {    //imgBase64Str 是裁剪后base64格式的图片
             this.photo = imgBase64Str   //base64格式图片显示
          });
        });
      }
    });
  }

  


}

对图片进行裁剪

我这里新建的cropper-image页面

corp-image.html 代码

<ion-content class="content">
  <img #image [src]="img" [ngStyle]="{'visibility': visibility}">

  <button class="corpCancel" (click)="cancel()">取消</button>
  <button class="corpDefine" (click)="save()">确定</button>
</ion-content>

corp-image.css代码

.content {
    background-image: none;
  }
  .scroll-content{
    padding-top: 0px;
  }
  .corpDefine,.corpCancel{
    padding: 10px;
    background: #fff;
    width: 20%;
    position: absolute;
    bottom: 10%;
  }
  .corpCancel{
    left: 20%;
  }
  .corpDefine{
    left: 60%;
  }

corp-image.ts代码

import { Component, ElementRef, ViewChild } from '@angular/core';
import { Events, IonicPage, NavController, NavParams } from 'ionic-angular';

declare let Cropper;
        
@IonicPage()
@Component({
  selector: 'page-crop-image',
  templateUrl: 'crop-image.html',
})
export class CropImagePage {
  public img: string;    // 要裁剪的图片
  @ViewChild('image')
  public image: ElementRef;
  cropper;
  visibility = 'hidden';

  constructor(public navCtrl: NavController,
              public navParams: NavParams,
              public events: Events,) {
  }

  ionViewCanEnter() {
    let imageSrc = this.navParams.get('imageSrc');
    if (!imageSrc) {
      return false;
    }
    this.img = imageSrc;    //从上一页面拍照或者相册获取到的图片
  }


  ionViewDidEnter() {
    let option = {
      autoCropArea: 0.6, // 初始裁剪区占图片大小
      aspectRatio: 1, // 裁剪区宽高比例,如16/9
      minCropBoxWidth: 80, // 最小裁剪宽度
      minCropBoxHeight: 80, // 最小裁剪高度
      viewMode: 1, // 图片移动范围,0无限制,1图片必须包裁剪区
      dragMode: 'move', // move设置裁剪区只可移动
      toggleDragModeOnDblclick: false,
      cropBoxResizable: true,
      ready: () => {
        this.visibility = 'visible';
      }
    };
    this.cropper = new Cropper(this.image.nativeElement, option);
  }


  //点击确认裁剪完成并将图片返回上一页面
  save() {
    let cas = this.cropper.getCroppedCanvas();
    let imgBase64Str = cas.toDataURL('image/jpeg');  // 生成base64格式图片;
    this.events.publish('crop-image:result', imgBase64Str);
    this.navCtrl.pop();
  }
  cancel(){
    this.navCtrl.pop();
  }

  ionViewWillLeave() {
    this.events.unsubscribe('crop-image:result'); // 退出页面取消订阅
  }
}

以上涉及到ionic3图片拍照和选择相册功能

可以封装一个服务类,以便重复使用,我这里新建一个图片拍照相册 native-service服务类

ionic g provider native-service

它会在providers文件夹中帮你创建好,在app.module中导入

实际使用中直接在需要的页面引入就可以,上面的点击图片裁剪页面中就有引入,这样就可以直接使用其中的方法了。

import {NativeServiceProvider} from "../../../../providers/native-service/native-service";


@Component({
  selector: 'change-info',
  templateUrl: 'change.html',
})

constructor(public nativeService:NativeServiceProvider,){
}

以下是图片拍照和相册选择功能 native-service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Camera, CameraOptions } from '@ionic-native/camera';
import { LoadingController, Loading, AlertController} from 'ionic-angular';
import { Observable} from 'Rxjs';
import { File, FileEntry} from '@ionic-native/file';


@Injectable()
export class NativeServiceProvider {

  private loading: Loading;
  private loadingIsOpen: boolean = false;

  TIME_OUT: number = 30000;
  IMAGE_SIZE = 1000;    // 拍照/从相册选择照片压缩大小
  QUALITY_SIZE = 94;    // 图像压缩质量,范围为0 - 100

  constructor(public http: HttpClient,
              private camera :Camera,
              private alertCtrl: AlertController,
              private loadingCtrl: LoadingController,
              private file: File) {
    
  }
  /**
   * 统一调用此方法显示loading
   */
  showLoading(content: string = ''): void {
    if (!this.loadingIsOpen) {
      this.loadingIsOpen = true;
      this.loading = this.loadingCtrl.create({
        content: content,
        spinner: 'dots',
        dismissOnPageChange: true,    // 是否在切换页面之后关闭loading框
        showBackdrop: false           // 是否显示遮罩层
      });
      this.loading.present();
      setTimeout(() => {
        this.loadingIsOpen && this.loading.dismiss();
        this.loadingIsOpen = false;
      }, this.TIME_OUT);
    }
  }

  /**
   * 关闭loading
   */
  hideLoading(): void {
    this.loadingIsOpen && this.loading.dismiss();
    this.loadingIsOpen = false;
  }

  /**
   * 使用cordova-plugin-camera获取照片
   */
  getPicture(options: CameraOptions = {}): Observable<string> {
    let ops: CameraOptions = Object.assign({
      sourceType: this.camera.PictureSourceType.CAMERA, // 图片来源,CAMERA:拍照,PHOTOLIBRARY:相册
      destinationType: this.camera.DestinationType.DATA_URL, // 默认返回base64字符串,DATA_URL:base64   FILE_URI:图片路径
      quality: this.QUALITY_SIZE, // 图像质量,范围为0 - 100
      allowEdit: false, // 选择图片前是否允许编辑
      encodingType: this.camera.EncodingType.JPEG,
      targetWidth: this.IMAGE_SIZE, // 缩放图像的宽度(像素)
      targetHeight: this.IMAGE_SIZE, // 缩放图像的高度(像素)
      saveToPhotoAlbum: false, // 是否保存到相册
      correctOrientation: true // 设置摄像机拍摄的图像是否为正确的方向
    }, options);
    return Observable.create(observer => {
      this.camera.getPicture(ops).then((imgData: string) => {
        if (ops.destinationType === this.camera.DestinationType.DATA_URL) {
          observer.next(imgData);
        } else {
          observer.next(imgData);
        }
      }).catch(err => {
        this.hideLoading();
        if (err === 20) {
          this.alert('没有权限,请在设置中开启权限');
          return;
        }
        if (String(err).indexOf('cancel') !== -1) {
          return;
        }
        console.log(err, '获取照片失败');
        this.alert('获取照片失败');
      });
    });
  }

  /**
   * 拍照获取照片
   */
  getPictureByCamera(options: CameraOptions = {}): Observable<string> {
    let ops: CameraOptions = Object.assign({
      sourceType: this.camera.PictureSourceType.CAMERA,
      correctOrientation: true,
      destinationType: this.camera.DestinationType.DATA_URL // DATA_URL: 0 base64字符串, FILE_URI: 1图片路径
    }, options);
    return this.getPicture(ops);
  };

  /**
   * 图库获取照片
   */
  getPictureByPhotoLibrary(options: CameraOptions = {}): Observable<string> {
    let ops: CameraOptions = Object.assign({
      sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
      correctOrientation: true,
      destinationType: this.camera.DestinationType.DATA_URL // DATA_URL: 0 base64字符串, FILE_URI: 1图片路径
    }, options);
    return this.getPicture(ops);
  };

  /**
   * 根据图片绝对路径转化为base64字符串
   */
  convertImgToBase64(path: string): Observable<string> {
    return Observable.create(observer => {
      this.file.resolveLocalFilesystemUrl(path).then((fileEnter: FileEntry) => {
        fileEnter.file(file => {
          let reader = new FileReader();
          reader.onloadend = function (e) {
            observer.next(this.result);
          };
          reader.readAsDataURL(file);
        });
      }).catch(err => {
        console.log(err, '根据图片绝对路径转化为base64字符串失败');
      });
    });
  }

  /**
   * 弹出提示框
   */
  alert(title: string, subTitle: string = ''): void {
    this.alertCtrl.create({
      title: title,
      subTitle: subTitle,
      buttons: [{text: '确定'}]
    }).present();
  }
}

其中涉及到的插件需要安装,然后在app.module.ts中导入,在实际使用的页面中引入就可以使用

以上就是图片裁剪的全部过程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值