Help with Image load


#1

I’m trying to load and display a previously image saved as base64 (:nativescript: + :nng:).

Simplified Component:

import { takePicture, requestPermissions } from "nativescript-camera";
import { RouterExtensions } from "nativescript-angular/router";

import { Component, OnInit, NgZone, ViewChild, ElementRef } from "@angular/core";

import { Page } from "ui/page";
import { Image } from "ui/image";

import { ImageSource } from "image-source";

 @Component({
	selector: "ns-vistoria",
	moduleId: module.id,
	templateUrl: "./os-vistoria.component.html",
	styleUrls: ["./os-vistoria-common.css"]
})
export class OSVistoriaComponent implements OnInit {
	vistoria: OrdemServicoVistoria;
	imageSource: ImageSource;
	fotoVistoria: Image;
	 @ ViewChild("fotoVistoria")fotoVistoriaImage: ElementRef;

	constructor(
		private page: Page,
		private zone: NgZone,
		private routerExtensions: RouterExtensions) {}

	ngOnInit() {
		this.vistoria = ...;
	}

    ngAfterViewInit() {
        this.initPhoto();
    }

	initPhoto() {
		console.log('********************************************** initPhoto() **********************************************');
		if (!this.vistoria.photobase64) {
			return;
		}

		let imageSource = new ImageSource();

		imageSource.fromBase64(this.vistoria.photobase64)
		.then(res => {
			console.log(res);
			if (res) {
				this.zone.run(() => {
					let fotoVistoria =  < Image > this.fotoVistoriaImage.nativeElement;
					fotoVistoria.imageSource = imageSource;
					this.fotoVistoria = fotoVistoria;
					this.fotoVistoria.imageSource = imageSource;
				});
			}
		});
	}

	...

Simplified Page:

<StackLayout orientation="vertical">
	<Image #fotoVistoria stretch="none" horizontalAlignment="center" verticalAlignment="center"></Image>
</StackLayout>

Nothing happens (nor errors); res in my trial is true and I manage to save and display the picture taken in a similar way, the first time I take the picture.

Any ideas?

Thanks!


#2

Try using <Image [src]="imageSrc"></Image>

I guess in your case fotoVistoria.src = imageSource;

I struggled and finally got this working, but then started getting out of memory errors on android when using imagesource. So even when you think it’s working I recommend doing some tests to make sure the garbage collector does it’s thing correctly. I’m still stuck at that part :frowning:


#3

What is imageSrc in this case?


#4

An ImageSource…

public imageSrc: ImageSource;

and in my constructor I have something like:

let folder = fs.knownFolders.documents();
this.imageSrc = imageSource.fromFile(fs.path.join(folder.path, `${this.individual.species.genus}_${this.individual.species.species}.png`));

#5

If you’re getting OOM issues - I’d switch to using Fresco for android - just wrap the UI in <android> <frescoStuff></android <ios> <Image /></ios> takes a bit more work but 99.9999% of the time you won’t have OOM issues on android @jeffswitzer


#6

Thanks Brad! Was beginning to think I was at a dead end but hadn’t seen nativescript-fresco. I’ll take it for a test run tomorrow.


#7

Hey @jeffswitzer, I tried something like your suggestion, no luck. My last trial:

<Image #fotoVistoria stretch="none" horizontalAlignment="center" verticalAlignment="center"  [src]="imageSource"></Image>
initPhotos() {
        console.log('********************************************** initPhotos() **********************************************');
        if (!this.vistoria.fotoVistoria) {
            return;
        }

        this.zone.run(() => {
            this.imageSource = new ImageSource();
            this.imageSource.loadFromBase64(this.vistoria.fotoVistoria);
        });
    }

#8

Have you ran a debugger on that code or stuck a console log inside the zone.run callback? I see that you return out of the function if this.vistoria.fotoVistoria doesn’t exist. I’d check to make sure that the new ImageSource() code is actually getting called. Also another test you can run is instead of [src]=“imageSource” try [src]=“http path to some image” and see if that even shows up.


#9

Nice suggestion, @jeffswitzer!
So, entering the URL of an image, it’s not displayed too:

<StackLayout orientation="vertical">
	<Label text="Foto da Vistoria" class="label-title"></Label>
	<GridLayout columns="auto, *, auto">
		<StackLayout orientation="vertical" col="0" (tap)="tirarFoto($event)" verticalAlignment="center">
			<Label class="mdi tirarFotoIco" [text]="'mdi-camera-enhance' | fonticon" horizontalAlignment="center"></Label>
			<Label class="small-font underline-text" [text]="'Tirar foto'" horizontalAlignment="center"></Label>
		</StackLayout>
		<Image #fotoVistoria stretch="none" horizontalAlignment="center" verticalAlignment="center" col="1"
			[src]="'https://docs.nativescript.org/img/cli-getting-started/angular/chapter0/NativeScript_logo.png'"></Image>
		<Label class="mdi apagarFotoIco" padding="10" [text]="'mdi-delete-forever' | fonticon" horizontalAlignment="center" verticalAlignment="center"
			(tap)="removerFotoVistoria()" [visibility]="fotoVistoria.imageSource ? 'visible' : 'collapse'"
			col="2"></Label>
	</GridLayout>
</StackLayout>

The result:

No errors. I commented out that initPhotos() part, to don’t invalidate the test.
Do you see anything wrong or what more could I check?

Thanks!


#10

Oops, I lied. Some seconds after, this error comes:
Error in downloadBitmap - java.net.ConnectException: Connection refused


#11

@jeffswitzer my mistake.
Emulator is not reaching internet. So I putted an URL of an internal address and the image is displayed.


#12

About the other test:

initPhotos() {
        console.log('********************************************** initPhotos() **********************************************');
        if (!this.vistoria.fotoVistoria) {
            return;
        }

        this.zone.run(() => {
            console.log('zone code ');
            this.imageSource = new ImageSource();
            var loadedBase64 = this.imageSource.loadFromBase64(this.vistoria.fotoVistoria);
            console.log(loadedBase64);
        });
    }

Output:

JS: zone code
JS: true

#13

Suggestions anyone? @jen.looper? Didn’t manage to solve it yet :frowning:


#14

Seems it was a bug reported in an issue.
So I upgraded my project following these instructions, from 3.0 to 3.1.1 (latest), and now the image is being displayed!

Thanks for the attention and help.


#15

Glad it worked out. Also wanted to report that @bradwaynemartin suggestion to use nativescript-fresco really helped solve android oom errors I was getting related to loading images from disk.


#16

If you do android apps and display any images, first plugin to go for is fresco :smiley: glad it helped, not everyone knows about it. Need to see if the core docs mention using fresco on the images section, if not a PR to mention it would be sweet.