ソースを参照

Convert HEIC images on Android

Vishnu Mohandas 4 年 前
コミット
a6c3913af5

+ 9 - 8
lib/db/files_db.dart

@@ -97,7 +97,7 @@ class FilesDB {
     return await db.insert(table, _getRowForFile(file));
   }
 
-  Future<List<dynamic>> insertMultiple(List<File> files) async {
+  Future<void> insertMultiple(List<File> files) async {
     final db = await instance.database;
     var batch = db.batch();
     int batchCounter = 0;
@@ -113,7 +113,7 @@ class FilesDB {
       );
       batchCounter++;
     }
-    return await batch.commit();
+    await batch.commit(noResult: true);
   }
 
   Future<File> getFile(int generatedID) async {
@@ -333,17 +333,18 @@ class FilesDB {
   }
 
   Future<List<File>> getMatchingFiles(
-      String title, String deviceFolder, int creationTime, int modificationTime,
-      {String alternateTitle}) async {
+    String title,
+    String deviceFolder,
+    int creationTime,
+    int modificationTime,
+  ) async {
     final db = await instance.database;
     final rows = await db.query(
       table,
-      where: '''($columnTitle=? OR $columnTitle=?) AND 
-          $columnDeviceFolder=? AND $columnCreationTime=? AND 
-          $columnModificationTime=?''',
+      where: '''$columnTitle=? AND $columnDeviceFolder=? AND 
+          $columnCreationTime=? AND $columnModificationTime=?''',
       whereArgs: [
         title,
-        alternateTitle,
         deviceFolder,
         creationTime,
         modificationTime,

+ 1 - 3
lib/services/sync_service.dart

@@ -16,7 +16,6 @@ import 'package:photos/repositories/file_repository.dart';
 import 'package:photo_manager/photo_manager.dart';
 import 'package:photos/utils/file_sync_util.dart';
 import 'package:photos/utils/file_uploader.dart';
-import 'package:photos/utils/file_name_util.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:dio/dio.dart';
 import 'package:photos/models/file.dart';
@@ -237,8 +236,7 @@ class SyncService {
   Future _storeDiff(List<File> diff, int collectionID) async {
     for (File file in diff) {
       final existingFiles = await _db.getMatchingFiles(file.title,
-          file.deviceFolder, file.creationTime, file.modificationTime,
-          alternateTitle: getHEICFileNameForJPG(file));
+          file.deviceFolder, file.creationTime, file.modificationTime);
       if (existingFiles == null) {
         // File uploaded from a different device
         file.localID = null;

+ 0 - 14
lib/utils/file_name_util.dart

@@ -1,14 +0,0 @@
-import 'package:photos/models/file.dart';
-import 'package:path/path.dart';
-
-String getJPGFileNameForHEIC(File file) {
-  return extension(file.title) == ".HEIC"
-      ? basenameWithoutExtension(file.title) + ".JPG"
-      : file.title;
-}
-
-String getHEICFileNameForJPG(File file) {
-  return extension(file.title) == ".JPG"
-      ? basenameWithoutExtension(file.title) + ".HEIC"
-      : file.title;
-}

+ 14 - 4
lib/utils/file_util.dart

@@ -1,4 +1,5 @@
 import 'dart:io' as io;
+import 'dart:io';
 import 'dart:typed_data';
 
 import 'package:flutter_sodium/flutter_sodium.dart';
@@ -213,16 +214,25 @@ Future<io.File> _downloadAndDecrypt(File file, BaseCacheManager cacheManager,
     await CryptoUtil.decryptFile(encryptedFilePath, decryptedFilePath,
         Sodium.base642bin(file.fileDecryptionHeader), decryptFileKey(file));
     logger.info("File decrypted: " + file.uploadedFileID.toString());
-    io.File(encryptedFilePath).deleteSync();
-    final fileExtension = extension(file.title).substring(1).toLowerCase();
+    encryptedFile.deleteSync();
+    var fileExtension = extension(file.title).substring(1).toLowerCase();
+    var outputFile = decryptedFile;
+    if (Platform.isAndroid && fileExtension == "heic") {
+      outputFile = await FlutterImageCompress.compressAndGetFile(
+        decryptedFilePath,
+        decryptedFilePath + ".jpg",
+        keepExif: true,
+      );
+      decryptedFile.deleteSync();
+    }
     final cachedFile = await cacheManager.putFile(
       file.getDownloadUrl(),
-      decryptedFile.readAsBytesSync(),
+      outputFile.readAsBytesSync(),
       eTag: file.getDownloadUrl(),
       maxAge: Duration(days: 365),
       fileExtension: fileExtension,
     );
-    decryptedFile.deleteSync();
+    outputFile.deleteSync();
     fileDownloadsInProgress.remove(file.uploadedFileID);
     return cachedFile;
   }).catchError((e) {

+ 2 - 5
lib/utils/share_util.dart

@@ -47,12 +47,9 @@ Future<void> _shareImage(ProgressDialog dialog, File file) async {
   await dialog.show();
   final bytes = await getBytes(file);
   final filename = _getFilename(file.title);
-  final ext = extension(file.title);
-  final shareExt = file.title.endsWith(".HEIC")
-      ? "jpg"
-      : ext.substring(1, ext.length).toLowerCase();
+  final ext = extension(filename);
   await dialog.hide();
-  return Share.file(filename, filename, bytes, "image/" + shareExt);
+  return Share.file(filename, filename, bytes, "image/" + ext);
 }
 
 String _getFilename(String name) {

+ 1 - 0
thirdparty/flutter_image_compress

@@ -0,0 +1 @@
+Subproject commit 9c4ae8e2e2cf81e8523cf137903ffd7f98b935bd