nativescript-sqlite icon indicating copy to clipboard operation
nativescript-sqlite copied to clipboard

Return and display blob into img example?

Open pchristou opened this issue 5 years ago • 3 comments

Hi,

I've created a table in Sqlite which has a column of type 'Blob'. I've uploaded images using the "DB Browser" GUI and I'm now looking to retrieve the rows into my nativescript-angular project. I can display the images on the UI if I store the images as base64 strings and simply update the image [src] attribute but I'd prefer to retrieve each rows Blob data and display that instead - I heard base64 data can be 33% larger than binary, plus this is what the blob data type was intended for?

When I retrieve the rows, the blob column for one row looks as follows:

image

How can I convert that into an Image I can display? Any guidance on this would be appreciated as I couldn't find anything suitable in the docs.

Many thanks, P

pchristou avatar Dec 09 '20 01:12 pchristou

Hi

I've used this code to store an image:

  const imageData = UIImageJPEGRepresentation(imageSource.ios, 1);
  sql = `INSERT INTO covers (bookid, big, small) VALUES (?, ?, ?)`;
  await this.execSql(sql, [bookid, imageData, imageData]);

and then this code to read it and write to disk:

        const sql = `SELECT ${imageField} FROM covers WHERE bookid=?`;
        const row = await this.getResult(sql, [bookid]);
        const coverData = row[imageField];
        const file = File.fromPath(fileName);
        file.writeSync(coverData);

stefalda avatar Dec 10 '20 21:12 stefalda

Thanks for your reply and sharing, it allowed me to try a few more things. What I'm trying to do is display images coming from a BLOB column stored in sqlite but couldn't find an example in how to do it using the nativescript-sqlite plugin. Here's the UI markup, pretty basic.

<Image *ngFor="let img of imgs" width="100" [src]="img"></Image>

In the component code, I'm looping through the retrieved results and trying to populate the .imgs array using the BLOB column with a compatible [src] value. Using the full base64 string works but I feel there must be a more efficient way(?).

            for (let i = 0; i < this.rows.length; i++) {
                const result = this.rows[i].Image;

                // not sure how to extract a meaningful value to push into the imgs array for Image [src].
                const blob = new Blob([result]);

                const reader = new FileReader();
                reader.readAsDataURL(blob);
                reader.onloadend = () => {
                    this.imgs.push(<any>reader.result); //  doesn't work - output: "data:;base64,W0JAMjQ3NjQxNg=="
                }
            }

And here's a few watches of the code above: image

A lot of SO answers refer to using URL.createObjectURL() to convert a Blob into img.src but this is a no go as the method isn't available on a native mobile app AFAIK (as it's attached to a web browsers object model).

pchristou avatar Dec 11 '20 00:12 pchristou

Yes, I haven't found a way to load the blob data from DB and then to display it in an image, so I resorted to saving it to disk and then reading it from disk...

stefalda avatar Dec 11 '20 14:12 stefalda