I´m trying to take a photo and analyze it with the tesseract OCR engine in ionic 3 App for iOS. I´m trying to run it on a iPhone 8 iOS 11.2.6
Unfortunately I get an error in Xcode
after taking a photo, and the app crashes:
NSURLConnection finished with error - code -1002 and also WARNING: sanitizing unsafe URL value assets-library://asset/asset.JPG?id=A791150A-3E89-400E-99D3-E7B3A3D888AA&ext=JPG
Thank you for your help
home.html
<h3 *ngIf="debugText">Debug: {{debugText}}</h3>
<span>{{recognizedText}}</span>
<!--<img src="assets/img/demo.png" #demoImg class="start-api" />-->
<img [src]="image" #imageResult />
<div *ngIf="_ocrIsLoaded && !image">
<!--<img src="assets/img/Start-arrow.png" #start class="start-arrow" />-->
</div>
home.ts:
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';
import Tesseract from 'tesseract.js';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
@ViewChild('imageResult') private imageResult: ElementRef;
@ViewChild('demoImg') private demoImg: ElementRef;
private recognizedText: string;
image: string = '';
_zone: any;
_ocrIsLoaded: boolean = false;
brightness: number = 12;
contrast: number = 52;
unsharpMask: any = { radius: 100, strength: 2 };
hue: number = -100;
saturation: number = -100;
showEditFilters: boolean = false;
debugText: string = '';
constructor(
private camera: Camera,
public navCtrl: NavController,
public platform: Platform,
public loadingCtrl: LoadingController,
public actionsheetCtrl: ActionSheetController) {
this._zone = new NgZone({ enableLongStackTrace: false });
}
openMenu() {
if (this._ocrIsLoaded === true) {
let actionSheet;
if (!this.image) {
actionSheet = this.actionsheetCtrl.create({
title: 'Actions',
cssClass: 'action-sheets-basic-page',
buttons: [
{
text: 'Random demo',
icon: !this.platform.is('ios') ? 'shuffle' : null,
handler: () => {
this.randomDemo()
}
},
{
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: 'Random demo',
icon: !this.platform.is('ios') ? 'shuffle' : null,
handler: () => {
this.randomDemo()
}
},
{
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()
}
},
{
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: 'Read image',
icon: !this.platform.is('ios') ? 'analytics' : null,
handler: () => {
this.analyze(this.imageResult.nativeElement.src, 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();
}
else {
alert('OCR API is not loaded');
}
}
restoreImage() {
if (this.image) {
this.imageResult.nativeElement.src = this.image;
}
}
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();
this.image = imageURI;
this.debugText = imageURI;
}, (err) => {
//console.log(`ERROR -> ${JSON.stringify(err)}`);
});
}
filter() {
/// 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);
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');
}
analyze(image, loadAPI) {
let loader = this.loadingCtrl.create({
content: 'Please wait...'
});
loader.present();
if (loadAPI == true) {
this._ocrIsLoaded = false;
}
/// Recognize data from image
Tesseract.recognize(image, {})
.progress((progress) => {
this._zone.run(() => {
loader.setContent(`${progress.status}: ${Math.floor(progress.progress * 100)}%`)
console.log('progress:', progress);
})
})
.then((tesseractResult) => {
this._zone.run(() => {
loader.dismissAll();
if (loadAPI == true) {
this._ocrIsLoaded = true;
}
console.log('Tesseract result: ');
console.log(tesseractResult);
/// Show a result if data isn't initializtion
if (loadAPI != true) { this.recognizedText = tesseractResult.text; }
});
});
}
randomDemo() {
}
ionViewDidLoad() {
console.log('loaded')
this.analyze(this.demoImg.nativeElement.src, true);
}
}
info.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>Diagnyzer</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIcons</key>
<dict/>
<key>CFBundleIcons~ipad</key>
<dict/>
<key>CFBundleIdentifier</key>
<string>io.ionic.diagnyzer</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.0.1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMainNibFile</key>
<string/>
<key>NSMainNibFile~ipad</key>
<string/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIRequiresFullScreen</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>ionic.local</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs read/write-access photo library access</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string/>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs write-access to photo library</string>
</dict>
</plist>
I do not know much about Ionic, but loading an img in Angular could cause an UnsafeUrl Exception.
Maybe you need to use a Dom Sanitizer.
DomSanitizer using example:
Inject it:
constructor(private sanitizer: DomSanitizer,) {}
And use a function to get the img content:
getImgContent(): SafeUrl {
return this.sanitizer.bypassSecurityTrustUrl(this.imgFile);
}
So you use in HTML Part:
<img class="object-img"
[src]="getImgContent()">
Answering a bit late, but try to add File Path plugin to your project. You can pass your URL and the plugin will resolve it.
Note that this plugin is supported only on Android devices
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With