mirror of
https://github.com/immich-app/immich.git
synced 2024-12-28 22:51:59 +00:00
Add support for Apple Pro Raw format (.DNG) (#60)
* Added '.dng' (AppleProRaw) to support file's type * Added OpenCV python framework for uniform image resizer * Added version number information
This commit is contained in:
parent
94514cfeea
commit
6e0ac79eae
9 changed files with 146 additions and 48 deletions
|
@ -13,6 +13,9 @@
|
||||||
## CPU BUILD
|
## CPU BUILD
|
||||||
FROM python:3.8 as cpu
|
FROM python:3.8 as cpu
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install ffmpeg libsm6 libxext6 -y
|
||||||
|
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
|
|
||||||
COPY ./requirements.txt /code/requirements.txt
|
COPY ./requirements.txt /code/requirements.txt
|
||||||
|
|
|
@ -2,15 +2,20 @@ from tensorflow.keras.applications import InceptionV3
|
||||||
from tensorflow.keras.applications.inception_v3 import preprocess_input, decode_predictions
|
from tensorflow.keras.applications.inception_v3 import preprocess_input, decode_predictions
|
||||||
from tensorflow.keras.preprocessing import image
|
from tensorflow.keras.preprocessing import image
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from PIL import Image
|
||||||
|
import cv2
|
||||||
IMG_SIZE = 299
|
IMG_SIZE = 299
|
||||||
PREDICTION_MODEL = InceptionV3(weights='imagenet')
|
PREDICTION_MODEL = InceptionV3(weights='imagenet')
|
||||||
|
|
||||||
|
|
||||||
def classify_image(image_path: str):
|
def classify_image(image_path: str):
|
||||||
img_path = f'./app/{image_path}'
|
img_path = f'./app/{image_path}'
|
||||||
img = image.load_img(img_path, target_size=(IMG_SIZE, IMG_SIZE))
|
# img = image.load_img(img_path, target_size=(IMG_SIZE, IMG_SIZE))
|
||||||
x = image.img_to_array(img)
|
|
||||||
|
target_image = cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
|
||||||
|
resized_target_image = cv2.resize(target_image, (IMG_SIZE, IMG_SIZE))
|
||||||
|
|
||||||
|
x = image.img_to_array(resized_target_image)
|
||||||
x = np.expand_dims(x, axis=0)
|
x = np.expand_dims(x, axis=0)
|
||||||
x = preprocess_input(x)
|
x = preprocess_input(x)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
opencv-python==4.5.5.64
|
||||||
fastapi>=0.68.0,<0.69.0
|
fastapi>=0.68.0,<0.69.0
|
||||||
pydantic>=1.8.0,<2.0.0
|
pydantic>=1.8.0,<2.0.0
|
||||||
uvicorn>=0.15.0,<0.16.0
|
uvicorn>=0.15.0,<0.16.0
|
||||||
|
|
|
@ -1,18 +1,36 @@
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/modules/home/providers/asset.provider.dart';
|
import 'package:immich_mobile/modules/home/providers/asset.provider.dart';
|
||||||
import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
|
import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
|
||||||
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
||||||
import 'package:immich_mobile/shared/providers/backup.provider.dart';
|
import 'package:immich_mobile/shared/providers/backup.provider.dart';
|
||||||
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
|
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
|
||||||
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
|
||||||
class ProfileDrawer extends ConsumerWidget {
|
class ProfileDrawer extends HookConsumerWidget {
|
||||||
const ProfileDrawer({Key? key}) : super(key: key);
|
const ProfileDrawer({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
AuthenticationState _authState = ref.watch(authenticationProvider);
|
AuthenticationState _authState = ref.watch(authenticationProvider);
|
||||||
|
final appInfo = useState({});
|
||||||
|
|
||||||
|
_getPackageInfo() async {
|
||||||
|
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||||
|
|
||||||
|
appInfo.value = {
|
||||||
|
"version": packageInfo.version,
|
||||||
|
"buildNumber": packageInfo.buildNumber,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
_getPackageInfo();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}, []);
|
||||||
|
|
||||||
return Drawer(
|
return Drawer(
|
||||||
shape: const RoundedRectangleBorder(
|
shape: const RoundedRectangleBorder(
|
||||||
|
@ -21,50 +39,68 @@ class ProfileDrawer extends ConsumerWidget {
|
||||||
bottomRight: Radius.circular(5),
|
bottomRight: Radius.circular(5),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: ListView(
|
child: Column(
|
||||||
padding: EdgeInsets.zero,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
DrawerHeader(
|
ListView(
|
||||||
decoration: BoxDecoration(
|
shrinkWrap: true,
|
||||||
color: Colors.grey[200],
|
padding: EdgeInsets.zero,
|
||||||
),
|
children: [
|
||||||
child: Column(
|
DrawerHeader(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
decoration: BoxDecoration(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
color: Colors.grey[200],
|
||||||
children: [
|
|
||||||
const Image(
|
|
||||||
image: AssetImage('assets/immich-logo-no-outline.png'),
|
|
||||||
width: 50,
|
|
||||||
filterQuality: FilterQuality.high,
|
|
||||||
),
|
),
|
||||||
const Padding(padding: EdgeInsets.all(8)),
|
child: Column(
|
||||||
Text(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
_authState.userEmail,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
style: TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold),
|
children: [
|
||||||
)
|
const Image(
|
||||||
],
|
image: AssetImage('assets/immich-logo-no-outline.png'),
|
||||||
),
|
width: 50,
|
||||||
),
|
filterQuality: FilterQuality.high,
|
||||||
ListTile(
|
),
|
||||||
tileColor: Colors.grey[100],
|
const Padding(padding: EdgeInsets.all(8)),
|
||||||
leading: const Icon(
|
Text(
|
||||||
Icons.logout_rounded,
|
_authState.userEmail,
|
||||||
color: Colors.black54,
|
style: TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold),
|
||||||
),
|
)
|
||||||
title: const Text(
|
],
|
||||||
"Sign Out",
|
),
|
||||||
style: TextStyle(color: Colors.black54, fontSize: 14),
|
),
|
||||||
),
|
ListTile(
|
||||||
onTap: () async {
|
tileColor: Colors.grey[100],
|
||||||
bool res = await ref.read(authenticationProvider.notifier).logout();
|
leading: const Icon(
|
||||||
|
Icons.logout_rounded,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
title: const Text(
|
||||||
|
"Sign Out",
|
||||||
|
style: TextStyle(color: Colors.black54, fontSize: 14),
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
bool res = await ref.read(authenticationProvider.notifier).logout();
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
ref.watch(backupProvider.notifier).cancelBackup();
|
ref.watch(backupProvider.notifier).cancelBackup();
|
||||||
ref.watch(assetProvider.notifier).clearAllAsset();
|
ref.watch(assetProvider.notifier).clearAllAsset();
|
||||||
ref.watch(websocketProvider.notifier).disconnect();
|
ref.watch(websocketProvider.notifier).disconnect();
|
||||||
AutoRouter.of(context).popUntilRoot();
|
AutoRouter.of(context).popUntilRoot();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
"Version V${appInfo.value["version"]}+${appInfo.value["buildNumber"]}",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.grey[400],
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -32,6 +32,9 @@ class FileHelper {
|
||||||
case 'heif':
|
case 'heif':
|
||||||
return {"type": "image", "subType": "heif"};
|
return {"type": "image", "subType": "heif"};
|
||||||
|
|
||||||
|
case 'dng':
|
||||||
|
return {"type": "image", "subType": "dng"};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return {"type": "unsupport", "subType": "unsupport"};
|
return {"type": "unsupport", "subType": "unsupport"};
|
||||||
}
|
}
|
||||||
|
|
|
@ -555,6 +555,48 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
|
package_info_plus:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: package_info_plus
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
package_info_plus_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_info_plus_linux
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.3"
|
||||||
|
package_info_plus_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_info_plus_macos
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0"
|
||||||
|
package_info_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_info_plus_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
|
package_info_plus_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_info_plus_web
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.4"
|
||||||
|
package_info_plus_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_info_plus_windows
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.4"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -36,6 +36,7 @@ dependencies:
|
||||||
# mapbox_gl: ^0.15.0
|
# mapbox_gl: ^0.15.0
|
||||||
flutter_map: ^0.14.0
|
flutter_map: ^0.14.0
|
||||||
flutter_udid: ^2.0.0
|
flutter_udid: ^2.0.0
|
||||||
|
package_info_plus: ^1.4.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -12,7 +12,7 @@ export const multerConfig = {
|
||||||
|
|
||||||
export const multerOption: MulterOptions = {
|
export const multerOption: MulterOptions = {
|
||||||
fileFilter: (req: Request, file: any, cb: any) => {
|
fileFilter: (req: Request, file: any, cb: any) => {
|
||||||
if (file.mimetype.match(/\/(jpg|jpeg|png|gif|mp4|x-msvideo|quicktime|heic|heif)$/)) {
|
if (file.mimetype.match(/\/(jpg|jpeg|png|gif|mp4|x-msvideo|quicktime|heic|heif|dng)$/)) {
|
||||||
cb(null, true);
|
cb(null, true);
|
||||||
} else {
|
} else {
|
||||||
cb(new HttpException(`Unsupported file type ${extname(file.originalname)}`, HttpStatus.BAD_REQUEST), false);
|
cb(new HttpException(`Unsupported file type ${extname(file.originalname)}`, HttpStatus.BAD_REQUEST), false);
|
||||||
|
|
|
@ -43,12 +43,19 @@ export class ImageOptimizeProcessor {
|
||||||
console.error('Error Reading File');
|
console.error('Error Reading File');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (savedAsset.mimeType == 'image/heic' || savedAsset.mimeType == 'image/heif') {
|
// Special Assets Type - ios
|
||||||
|
if (
|
||||||
|
savedAsset.mimeType == 'image/heic' ||
|
||||||
|
savedAsset.mimeType == 'image/heif' ||
|
||||||
|
savedAsset.mimeType == 'image/dng'
|
||||||
|
) {
|
||||||
let desitnation = '';
|
let desitnation = '';
|
||||||
if (savedAsset.mimeType == 'image/heic') {
|
if (savedAsset.mimeType == 'image/heic') {
|
||||||
desitnation = resizePath.replace('.HEIC', '.jpeg');
|
desitnation = resizePath.replace('.HEIC', '.jpeg');
|
||||||
} else {
|
} else if (savedAsset.mimeType == 'image/heif') {
|
||||||
desitnation = resizePath.replace('.HEIF', '.jpeg');
|
desitnation = resizePath.replace('.HEIF', '.jpeg');
|
||||||
|
} else if (savedAsset.mimeType == 'image/dng') {
|
||||||
|
desitnation = resizePath.replace('.DNG', '.jpeg');
|
||||||
}
|
}
|
||||||
|
|
||||||
sharp(data)
|
sharp(data)
|
||||||
|
|
Loading…
Reference in a new issue