Update thumbnail generation mechanism

This commit is contained in:
Vishnu Mohandas 2020-04-12 02:59:07 +05:30
parent a142e2694a
commit 5826f8a7e0
5 changed files with 24 additions and 42 deletions

View file

@ -11,6 +11,7 @@ class DatabaseHelper {
static final table = 'photos';
static final columnLocalId = 'local_id';
static final columnLocalPath = 'local_path';
static final columnThumbnailPath = 'thumbnail_path';
static final columnPath = 'path';
@ -42,6 +43,7 @@ class DatabaseHelper {
Future _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE $table (
$columnLocalId TEXT,
$columnLocalPath TEXT NOT NULL,
$columnThumbnailPath TEXT NOT NULL,
$columnPath TEXT,
@ -123,6 +125,7 @@ class DatabaseHelper {
Map<String, dynamic> _getRowForPhoto(Photo photo) {
var row = new Map<String, dynamic>();
row[columnLocalId] = photo.localId;
row[columnLocalPath] = photo.localPath;
row[columnThumbnailPath] = photo.thumbnailPath;
row[columnPath] = photo.path;

View file

@ -1,12 +1,10 @@
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:flutter/foundation.dart';
import 'package:image/image.dart';
import 'package:path_provider/path_provider.dart';
import 'package:photo_manager/photo_manager.dart';
class Photo {
String localId;
String path;
String localPath;
String thumbnailPath;
@ -22,7 +20,8 @@ class Photo {
syncTimestamp = json["syncTimestamp"];
Photo.fromRow(Map<String, dynamic> row)
: localPath = row["local_path"],
: localId = row["local_id"],
localPath = row["local_path"],
thumbnailPath = row["thumbnail_path"],
path = row["path"],
hash = row["hash"],
@ -33,34 +32,14 @@ class Photo {
static Future<Photo> fromAsset(AssetEntity asset) async {
Photo photo = Photo();
var file = (await asset.originFile);
photo.localId = asset.id;
photo.localPath = file.path;
photo.hash = getHash(file);
photo.thumbnailPath = file.path;
return photo;
}
static Future<Photo> setThumbnail(Photo photo) async {
var externalPath = (await getApplicationDocumentsDirectory()).path;
var thumbnailPath =
externalPath + "/photos/thumbnails/" + photo.hash + ".thumbnail";
var args = Map<String, String>();
args["assetPath"] = photo.localPath;
args["thumbnailPath"] = thumbnailPath;
photo.thumbnailPath = thumbnailPath;
return compute(getThumbnailPath, args).then((value) => photo);
}
static String getHash(File file) {
return sha256.convert(file.readAsBytesSync()).toString();
}
}
Future<void> getThumbnailPath(Map<String, String> args) async {
return File(args["thumbnailPath"])
..writeAsBytes(_getThumbnail(args["assetPath"]));
}
List<int> _getThumbnail(String path) {
Image image = decodeImage(File(path).readAsBytesSync());
return encodePng(copyResize(image, width: 250));
}

View file

@ -71,7 +71,7 @@ class FaceSearchResultsPage extends StatelessWidget {
future: DatabaseHelper.instance.getPhotoByPath(path),
builder: (_, snapshot) {
if (snapshot.hasData) {
return ImageWidget(path: snapshot.data.thumbnailPath);
return ImageWidget(snapshot.data);
} else if (snapshot.hasError) {
return Container(
margin: EdgeInsets.all(2),

View file

@ -68,7 +68,7 @@ class _GalleryState extends State<Gallery> {
},
child: Padding(
padding: const EdgeInsets.all(1.0),
child: ImageWidget(path: photo.thumbnailPath),
child: ImageWidget(photo),
),
);
}

View file

@ -1,17 +1,19 @@
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:myapp/core/lru_map.dart';
import 'package:myapp/models/photo.dart';
import 'package:myapp/photo_loader.dart';
import 'package:myapp/ui/loading_widget.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:provider/provider.dart';
class ImageWidget extends StatefulWidget {
final String path;
final Photo photo;
const ImageWidget({
const ImageWidget(
this.photo, {
Key key,
this.path,
}) : super(key: key);
@override
_ImageWidgetState createState() => _ImageWidgetState();
@ -22,7 +24,7 @@ class _ImageWidgetState extends State<ImageWidget> {
@override
Widget build(BuildContext context) {
final path = widget.path;
final path = widget.photo.localPath;
final size = 124;
final cachedImage = ImageLruCache.getData(path, size);
@ -31,12 +33,15 @@ class _ImageWidgetState extends State<ImageWidget> {
if (cachedImage != null) {
image = cachedImage;
} else {
image = FutureBuilder<Image>(
future: _buildImageWidget(path, size),
image = FutureBuilder<Uint8List>(
future:
AssetEntity(id: widget.photo.localId).thumbDataWithSize(size, size),
builder: (context, snapshot) {
if (snapshot.hasData) {
ImageLruCache.setData(path, size, snapshot.data);
return snapshot.data;
Image image = Image.memory(snapshot.data,
width: 124, height: 124, fit: BoxFit.cover);
ImageLruCache.setData(path, size, image);
return image;
} else {
return loadWidget;
}
@ -47,15 +52,10 @@ class _ImageWidgetState extends State<ImageWidget> {
return image;
}
Future<Image> _buildImageWidget(String path, num size) async {
return Image.file(File(path),
width: size.toDouble(), height: size.toDouble(), fit: BoxFit.cover);
}
@override
void didUpdateWidget(ImageWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.path != oldWidget.path) {
if (widget.photo.localPath != oldWidget.photo.localPath) {
setState(() {});
}
}