Last active
November 2, 2018 17:04
-
-
Save thEpisode/58b67f7027f28bd415768797287da322 to your computer and use it in GitHub Desktop.
Ionic 3.x image filters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ion-header> | |
<ion-navbar> | |
<ion-title> | |
Taking Photo | |
</ion-title> | |
</ion-navbar> | |
</ion-header> | |
<ion-content padding> | |
<img [src]="image" #imageResult /> | |
<div *ngIf="image && showEditFilters"> | |
<ion-list> | |
<ion-list-header> | |
Adjust Image Filters | |
</ion-list-header> | |
<ion-item> | |
<ion-label>Brightness</ion-label> | |
<ion-range min="-100" max="100" pin="true" step="1" [(ngModel)]="brightness" color="secondary"> | |
<ion-icon range-left small name="sunny"></ion-icon> | |
<ion-icon range-right name="sunny"></ion-icon> | |
</ion-range> | |
</ion-item> | |
<ion-item> | |
<ion-label>Contrast</ion-label> | |
<ion-range min="-100" max="100" pin="true" step="1" [(ngModel)]="contrast" color="secondary"> | |
<ion-icon range-left small name="contrast"></ion-icon> | |
<ion-icon range-right name="contrast"></ion-icon> | |
</ion-range> | |
</ion-item> | |
<ion-item> | |
<ion-label>UnsharpMask Radius</ion-label> | |
<ion-range min="0" max="200" pin="true" step="1" [(ngModel)]="unsharpMask.radius" color="secondary"> | |
<ion-icon range-left small name="ios-radio"></ion-icon> | |
<ion-icon range-right name="ios-radio"></ion-icon> | |
</ion-range> | |
</ion-item> | |
<ion-item> | |
<ion-label>UnsharpMask Strength</ion-label> | |
<ion-range min="0" max="5" step="0.5" pin="true" [(ngModel)]="unsharpMask.strength" color="secondary"> | |
<ion-icon range-left small name="md-cog"></ion-icon> | |
<ion-icon range-right name="md-cog"></ion-icon> | |
</ion-range> | |
</ion-item> | |
<ion-item> | |
<ion-label>Hue</ion-label> | |
<ion-range min="-100" max="100" pin="true" step="1" [(ngModel)]="hue" color="secondary"> | |
<ion-icon range-left small name="md-color-palette"></ion-icon> | |
<ion-icon range-right name="md-color-palette"></ion-icon> | |
</ion-range> | |
</ion-item> | |
<ion-item> | |
<ion-label>Saturation</ion-label> | |
<ion-range min="-100" max="100" pin="true" step="1" [(ngModel)]="saturation" color="secondary"> | |
<ion-icon range-left small name="thermometer"></ion-icon> | |
<ion-icon range-right name="thermometer"></ion-icon> | |
</ion-range> | |
</ion-item> | |
</ion-list> | |
</div> | |
<ion-fab right bottom> | |
<button ion-fab (click)="openMenu()" color="danger"><ion-icon name="add"></ion-icon></button> | |
</ion-fab> | |
</ion-content> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component, ViewChild, ElementRef, NgZone } from '@angular/core'; | |
import { NavController } from 'ionic-angular'; | |
import { Camera } from '@ionic-native/camera'; | |
import { Platform, ActionSheetController, LoadingController } from 'ionic-angular'; | |
@Component({ | |
selector: 'page-home', | |
templateUrl: 'home.html' | |
}) | |
export class HomePage { | |
@ViewChild('imageResult') private imageResult: ElementRef; // reference to DOM element | |
image: string = ''; | |
_zone: any; | |
brightness: number = 12; | |
contrast: number = 52; | |
unsharpMask: any = { radius: 100, strength: 2 }; | |
hue: number = -100; | |
saturation: number = -100; | |
showEditFilters: boolean = false; | |
constructor( | |
private camera: Camera, | |
public navCtrl: NavController, | |
public platform: Platform, | |
public loadingCtrl: LoadingController, | |
public actionsheetCtrl: ActionSheetController) { | |
this._zone = new NgZone({ enableLongStackTrace: false }); | |
} | |
/// Execute a menu | |
openMenu() { | |
let actionSheet; | |
if (!this.image) { | |
actionSheet = this.actionsheetCtrl.create({ | |
title: 'Actions', | |
cssClass: 'action-sheets-basic-page', | |
buttons: [ | |
{ | |
text: 'Take Photo', | |
icon: !this.platform.is('ios') ? 'camera' : null, | |
handler: () => { | |
this.takePicture() | |
} | |
}, | |
{ | |
text: 'Cancel', | |
role: 'cancel', // will always sort to be on the bottom | |
icon: !this.platform.is('ios') ? 'close' : null, | |
handler: () => { | |
console.log('Cancel clicked'); | |
} | |
} | |
] | |
}); | |
} | |
else { | |
actionSheet = this.actionsheetCtrl.create({ | |
title: 'Actions', | |
cssClass: 'action-sheets-basic-page', | |
buttons: [ | |
{ | |
text: 'Re-Take photo', | |
icon: !this.platform.is('ios') ? 'camera' : null, | |
handler: () => { | |
this.takePicture() | |
} | |
}, | |
{ | |
text: 'Apply filters', | |
icon: !this.platform.is('ios') ? 'barcode' : null, | |
handler: () => { | |
this.filter(this.imageResult.nativeElement.src) | |
} | |
}, | |
{ | |
text: 'Clean filters', | |
icon: !this.platform.is('ios') ? 'refresh' : null, | |
handler: () => { | |
this.restoreImage() | |
} | |
}, | |
{ | |
text: this.showEditFilters == false ? 'Customize filters' : 'Hide customization filters', | |
icon: !this.platform.is('ios') ? 'hammer' : null, | |
handler: () => { | |
this.showEditFilters = this.showEditFilters == false ? true : false; | |
} | |
}, | |
{ | |
text: 'Cancel', | |
role: 'cancel', // will always sort to be on the bottom | |
icon: !this.platform.is('ios') ? 'close' : null, | |
handler: () => { | |
console.log('Cancel clicked'); | |
} | |
} | |
] | |
}); | |
} | |
actionSheet.present(); | |
} | |
restoreImage() { | |
if (this.image) { | |
this.imageResult.nativeElement.src = this.image; | |
} | |
} | |
filter(image) { | |
/// Initialization of glfx.js | |
/// is important, to use js memory elements | |
/// access to Window element through (<any>window) | |
try { | |
var canvas = (<any>window).fx.canvas(); | |
} catch (e) { | |
alert(e); | |
return; | |
} | |
/// taken from glfx documentation | |
var imageElem = this.imageResult.nativeElement; // another trick is acces to DOM element | |
var texture = canvas.texture(imageElem); | |
/// filters applied to clean text | |
canvas.draw(texture) | |
.hueSaturation(this.hue / 100, this.saturation / 100)//grayscale | |
.unsharpMask(this.unsharpMask.radius, this.unsharpMask.strength) | |
.brightnessContrast(this.brightness / 100, this.contrast / 100) | |
.update(); | |
/// replace image src | |
imageElem.src = canvas.toDataURL('image/png'); | |
} | |
takePicture() { | |
let loader = this.loadingCtrl.create({ | |
content: 'Please wait...' | |
}); | |
loader.present(); | |
// Take a picture saving in device, as jpg and allows edit | |
this.camera.getPicture({ | |
quality: 100, | |
destinationType: this.camera.DestinationType.NATIVE_URI, | |
encodingType: this.camera.EncodingType.JPEG, | |
targetHeight: 1000, | |
sourceType: 1, | |
allowEdit: true, | |
saveToPhotoAlbum: true, | |
correctOrientation: true | |
}).then((imageURI) => { | |
loader.dismissAll(); | |
// bind the URI returned by API | |
this.image = imageURI; | |
}, (err) => { | |
console.log(`ERROR -> ${JSON.stringify(err)}`); | |
}); | |
} | |
} |
@affandyy what this gist doesn't show you is that glfx library being loaded (i.e fx has not been loaded, which is the glfx library).
I've just received this error myself, and looking at the code within filterimage: var canvas = (window).fx.canvas();
what you need to do is download glfx from http://evanw.github.io/glfx.js/glfx.js I stored it under assets/scripts/glfx.js
Next locate your index.html and load the script :
<script src="assets/script/glfx.js"></script>Then try again.
image rotate when i set filters in ios on android work fine
please can u help me
thanks in advance
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Error occured:
Typeerror: cannot read property 'canvas' of undefined