准备
开始
下载上面两个文件,将文件保存到 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中导入,在实际使用的页面中引入就可以使用
以上就是图片裁剪的全部过程