mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-03-28 09:51:36 +01:00
Allow setting resolution of enhanced photos
This commit is contained in:
parent
08a7e6f09d
commit
e7a89c93af
11 changed files with 336 additions and 21 deletions
|
@ -365,6 +365,13 @@
|
|||
},
|
||||
"settingsShowDateInAlbumTitle": "Group photos by date",
|
||||
"settingsShowDateInAlbumDescription": "Apply only when the album is sorted by time",
|
||||
"settingsPhotoEnhancementTitle": "Photo enhancement",
|
||||
"settingsPhotoEnhancementPageTitle": "Photo enhancement settings",
|
||||
"@settingsPhotoEnhancementPageTitle": {
|
||||
"description": "Dedicated page for photo enhancement settings"
|
||||
},
|
||||
"settingsEnhanceMaxResolutionTitle": "Max output resolution",
|
||||
"settingsEnhanceMaxResolutionDescription": "Photos larger than the selected resolution will be downscaled.\n\nHigh resolution photos require significantly more memory and time to process. Please lower this setting if the app crashed while enhancing your photos.",
|
||||
"settingsThemeTitle": "Theme",
|
||||
"settingsThemeDescription": "Customize the appearance of the app",
|
||||
"settingsThemePageTitle": "Theme settings",
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
"settingsAlbumPageTitle",
|
||||
"settingsShowDateInAlbumTitle",
|
||||
"settingsShowDateInAlbumDescription",
|
||||
"settingsPhotoEnhancementTitle",
|
||||
"settingsPhotoEnhancementPageTitle",
|
||||
"settingsEnhanceMaxResolutionTitle",
|
||||
"settingsEnhanceMaxResolutionDescription",
|
||||
"settingsExperimentalTitle",
|
||||
"settingsExperimentalDescription",
|
||||
"settingsExperimentalPageTitle",
|
||||
|
@ -109,6 +113,10 @@
|
|||
"settingsAlbumPageTitle",
|
||||
"settingsShowDateInAlbumTitle",
|
||||
"settingsShowDateInAlbumDescription",
|
||||
"settingsPhotoEnhancementTitle",
|
||||
"settingsPhotoEnhancementPageTitle",
|
||||
"settingsEnhanceMaxResolutionTitle",
|
||||
"settingsEnhanceMaxResolutionDescription",
|
||||
"settingsExperimentalTitle",
|
||||
"settingsExperimentalDescription",
|
||||
"settingsExperimentalPageTitle",
|
||||
|
@ -224,6 +232,10 @@
|
|||
"settingsAlbumPageTitle",
|
||||
"settingsShowDateInAlbumTitle",
|
||||
"settingsShowDateInAlbumDescription",
|
||||
"settingsPhotoEnhancementTitle",
|
||||
"settingsPhotoEnhancementPageTitle",
|
||||
"settingsEnhanceMaxResolutionTitle",
|
||||
"settingsEnhanceMaxResolutionDescription",
|
||||
"settingsThemeTitle",
|
||||
"settingsThemeDescription",
|
||||
"settingsThemePageTitle",
|
||||
|
@ -362,6 +374,10 @@
|
|||
],
|
||||
|
||||
"es": [
|
||||
"settingsPhotoEnhancementTitle",
|
||||
"settingsPhotoEnhancementPageTitle",
|
||||
"settingsEnhanceMaxResolutionTitle",
|
||||
"settingsEnhanceMaxResolutionDescription",
|
||||
"rootPickerSkipConfirmationDialogContent2",
|
||||
"helpButtonLabel",
|
||||
"backgroundServiceStopping",
|
||||
|
@ -374,6 +390,10 @@
|
|||
],
|
||||
|
||||
"fi": [
|
||||
"settingsPhotoEnhancementTitle",
|
||||
"settingsPhotoEnhancementPageTitle",
|
||||
"settingsEnhanceMaxResolutionTitle",
|
||||
"settingsEnhanceMaxResolutionDescription",
|
||||
"enhanceTooltip",
|
||||
"enhanceLowLightTitle",
|
||||
"collectionEnhancedPhotosLabel",
|
||||
|
@ -383,6 +403,10 @@
|
|||
|
||||
"fr": [
|
||||
"collectionsTooltip",
|
||||
"settingsPhotoEnhancementTitle",
|
||||
"settingsPhotoEnhancementPageTitle",
|
||||
"settingsEnhanceMaxResolutionTitle",
|
||||
"settingsEnhanceMaxResolutionDescription",
|
||||
"helpTooltip",
|
||||
"helpButtonLabel",
|
||||
"removeFromAlbumTooltip",
|
||||
|
@ -394,6 +418,10 @@
|
|||
],
|
||||
|
||||
"pl": [
|
||||
"settingsPhotoEnhancementTitle",
|
||||
"settingsPhotoEnhancementPageTitle",
|
||||
"settingsEnhanceMaxResolutionTitle",
|
||||
"settingsEnhanceMaxResolutionDescription",
|
||||
"createCollectionTooltip",
|
||||
"createCollectionDialogAlbumLabel",
|
||||
"createCollectionDialogAlbumDescription",
|
||||
|
@ -423,6 +451,10 @@
|
|||
],
|
||||
|
||||
"pt": [
|
||||
"settingsPhotoEnhancementTitle",
|
||||
"settingsPhotoEnhancementPageTitle",
|
||||
"settingsEnhanceMaxResolutionTitle",
|
||||
"settingsEnhanceMaxResolutionDescription",
|
||||
"enhanceTooltip",
|
||||
"enhanceLowLightTitle",
|
||||
"collectionEnhancedPhotosLabel",
|
||||
|
@ -431,6 +463,10 @@
|
|||
],
|
||||
|
||||
"ru": [
|
||||
"settingsPhotoEnhancementTitle",
|
||||
"settingsPhotoEnhancementPageTitle",
|
||||
"settingsEnhanceMaxResolutionTitle",
|
||||
"settingsEnhanceMaxResolutionDescription",
|
||||
"enhanceTooltip",
|
||||
"enhanceLowLightTitle",
|
||||
"collectionEnhancedPhotosLabel",
|
||||
|
|
|
@ -172,6 +172,20 @@ class Pref {
|
|||
value,
|
||||
(key, value) => provider.setBool(key, value));
|
||||
|
||||
int? getEnhanceMaxWidth() => provider.getInt(PrefKey.enhanceMaxWidth);
|
||||
int getEnhanceMaxWidthOr([int def = 2048]) => getEnhanceMaxWidth() ?? def;
|
||||
Future<bool> setEnhanceMaxWidth(int value) => _set<int>(
|
||||
PrefKey.enhanceMaxWidth,
|
||||
value,
|
||||
(key, value) => provider.setInt(key, value));
|
||||
|
||||
int? getEnhanceMaxHeight() => provider.getInt(PrefKey.enhanceMaxHeight);
|
||||
int getEnhanceMaxHeightOr([int def = 1536]) => getEnhanceMaxHeight() ?? def;
|
||||
Future<bool> setEnhanceMaxHeight(int value) => _set<int>(
|
||||
PrefKey.enhanceMaxHeight,
|
||||
value,
|
||||
(key, value) => provider.setInt(key, value));
|
||||
|
||||
Future<bool> _set<T>(PrefKey key, T value,
|
||||
Future<bool> Function(PrefKey key, T value) setFn) async {
|
||||
if (await setFn(key, value)) {
|
||||
|
@ -461,6 +475,8 @@ enum PrefKey {
|
|||
isAlbumBrowserShowDate,
|
||||
gpsMapProvider,
|
||||
hasShownSharedAlbumInfo,
|
||||
enhanceMaxWidth,
|
||||
enhanceMaxHeight,
|
||||
|
||||
// account pref
|
||||
isEnableFaceRecognitionApp,
|
||||
|
@ -515,6 +531,10 @@ extension on PrefKey {
|
|||
return "gpsMapProvider";
|
||||
case PrefKey.hasShownSharedAlbumInfo:
|
||||
return "hasShownSharedAlbumInfo";
|
||||
case PrefKey.enhanceMaxWidth:
|
||||
return "enhanceMaxWidth";
|
||||
case PrefKey.enhanceMaxHeight:
|
||||
return "enhanceMaxHeight";
|
||||
|
||||
// account pref
|
||||
case PrefKey.isEnableFaceRecognitionApp:
|
||||
|
|
|
@ -11,6 +11,7 @@ import 'package:nc_photos/mobile/android/android_info.dart';
|
|||
import 'package:nc_photos/mobile/android/permission_util.dart';
|
||||
import 'package:nc_photos/object_extension.dart';
|
||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||
import 'package:nc_photos/pref.dart';
|
||||
import 'package:nc_photos/snack_bar_manager.dart';
|
||||
import 'package:nc_photos_plugin/nc_photos_plugin.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
@ -67,6 +68,8 @@ class EnhanceHandler {
|
|||
await ImageProcessor.zeroDce(
|
||||
"${account.url}/${file.path}",
|
||||
file.filename,
|
||||
Pref().getEnhanceMaxWidthOr(),
|
||||
Pref().getEnhanceMaxHeightOr(),
|
||||
headers: {
|
||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
||||
},
|
||||
|
@ -77,6 +80,8 @@ class EnhanceHandler {
|
|||
await ImageProcessor.deepLab3Portrait(
|
||||
"${account.url}/${file.path}",
|
||||
file.filename,
|
||||
Pref().getEnhanceMaxWidthOr(),
|
||||
Pref().getEnhanceMaxHeightOr(),
|
||||
headers: {
|
||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
||||
},
|
||||
|
|
|
@ -25,6 +25,7 @@ import 'package:nc_photos/widget/root_picker.dart';
|
|||
import 'package:nc_photos/widget/share_folder_picker.dart';
|
||||
import 'package:nc_photos/widget/stateful_slider.dart';
|
||||
import 'package:screen_brightness/screen_brightness.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class SettingsArguments {
|
||||
|
@ -137,6 +138,15 @@ class _SettingsState extends State<Settings> {
|
|||
description: L10n.global().settingsAlbumDescription,
|
||||
builder: () => _AlbumSettings(),
|
||||
),
|
||||
_buildSubSettings(
|
||||
context,
|
||||
leading: Icon(
|
||||
Icons.auto_fix_high_outlined,
|
||||
color: AppTheme.getUnfocusedIconColor(context),
|
||||
),
|
||||
label: L10n.global().settingsPhotoEnhancementTitle,
|
||||
builder: () => _EnhancementSettings(),
|
||||
),
|
||||
_buildSubSettings(
|
||||
context,
|
||||
leading: Icon(
|
||||
|
@ -956,6 +966,216 @@ class _AlbumSettingsState extends State<_AlbumSettings> {
|
|||
static final _log = Logger("widget.settings._AlbumSettingsState");
|
||||
}
|
||||
|
||||
class _EnhancementSettings extends StatefulWidget {
|
||||
@override
|
||||
createState() => _EnhancementSettingsState();
|
||||
}
|
||||
|
||||
class _EnhancementSettingsState extends State<_EnhancementSettings> {
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
_maxWidth = Pref().getEnhanceMaxWidthOr();
|
||||
_maxHeight = Pref().getEnhanceMaxHeightOr();
|
||||
}
|
||||
|
||||
@override
|
||||
build(BuildContext context) {
|
||||
return AppTheme(
|
||||
child: Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => _buildContent(context),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildContent(BuildContext context) {
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
title: Text(L10n.global().settingsPhotoEnhancementPageTitle),
|
||||
),
|
||||
SliverList(
|
||||
delegate: SliverChildListDelegate(
|
||||
[
|
||||
ListTile(
|
||||
title: Text(L10n.global().settingsEnhanceMaxResolutionTitle),
|
||||
subtitle: Text("${_maxWidth}x$_maxHeight"),
|
||||
onTap: () => _onMaxResolutionTap(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onMaxResolutionTap(BuildContext context) async {
|
||||
var width = _maxWidth;
|
||||
var height = _maxHeight;
|
||||
final result = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (_) => AppTheme(
|
||||
child: AlertDialog(
|
||||
title: Text(L10n.global().settingsEnhanceMaxResolutionTitle),
|
||||
content: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(L10n.global().settingsEnhanceMaxResolutionDescription),
|
||||
const SizedBox(height: 16),
|
||||
_EnhanceResolutionSlider(
|
||||
initialWidth: _maxWidth,
|
||||
initialHeight: _maxHeight,
|
||||
onChanged: (value) {
|
||||
width = value.item1;
|
||||
height = value.item2;
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
child: Text(MaterialLocalizations.of(context).okButtonLabel),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
if (result != true || (width == _maxWidth && height == _maxHeight)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_setMaxResolution(width, height);
|
||||
}
|
||||
|
||||
Future<void> _setMaxResolution(int width, int height) async {
|
||||
_log.info(
|
||||
"[_setMaxResolution] ${_maxWidth}x$_maxHeight -> ${width}x$height");
|
||||
final oldWidth = _maxWidth;
|
||||
final oldHeight = _maxHeight;
|
||||
setState(() {
|
||||
_maxWidth = width;
|
||||
_maxHeight = height;
|
||||
});
|
||||
if (!await Pref().setEnhanceMaxWidth(width) ||
|
||||
!await Pref().setEnhanceMaxHeight(height)) {
|
||||
_log.severe("[_setMaxResolution] Failed writing pref");
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(L10n.global().writePreferenceFailureNotification),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
await Pref().setEnhanceMaxWidth(oldWidth);
|
||||
setState(() {
|
||||
_maxWidth = oldWidth;
|
||||
_maxHeight = oldHeight;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
late int _maxWidth;
|
||||
late int _maxHeight;
|
||||
|
||||
static final _log = Logger("widget.settings._EnhancementSettingsState");
|
||||
}
|
||||
|
||||
class _EnhanceResolutionSlider extends StatefulWidget {
|
||||
const _EnhanceResolutionSlider({
|
||||
Key? key,
|
||||
required this.initialWidth,
|
||||
required this.initialHeight,
|
||||
this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
createState() => _EnhanceResolutionSliderState();
|
||||
|
||||
final int initialWidth;
|
||||
final int initialHeight;
|
||||
final ValueChanged<Tuple2<int, int>>? onChanged;
|
||||
}
|
||||
|
||||
class _EnhanceResolutionSliderState extends State<_EnhanceResolutionSlider> {
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
_width = widget.initialWidth;
|
||||
_height = widget.initialHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Text("${_width}x$_height"),
|
||||
),
|
||||
StatefulSlider(
|
||||
initialValue: resolutionToSliderValue(_width).toDouble(),
|
||||
min: -3,
|
||||
max: 3,
|
||||
divisions: 6,
|
||||
onChangeEnd: (value) async {
|
||||
final resolution = sliderValueToResolution(value.toInt());
|
||||
setState(() {
|
||||
_width = resolution.item1;
|
||||
_height = resolution.item2;
|
||||
});
|
||||
widget.onChanged?.call(resolution);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
static Tuple2<int, int> sliderValueToResolution(int value) {
|
||||
switch (value) {
|
||||
case -3:
|
||||
return const Tuple2(1024, 768);
|
||||
case -2:
|
||||
return const Tuple2(1280, 960);
|
||||
case -1:
|
||||
return const Tuple2(1600, 1200);
|
||||
case 1:
|
||||
return const Tuple2(2560, 1920);
|
||||
case 2:
|
||||
return const Tuple2(3200, 2400);
|
||||
case 3:
|
||||
return const Tuple2(4096, 3072);
|
||||
default:
|
||||
return const Tuple2(2048, 1536);
|
||||
}
|
||||
}
|
||||
|
||||
static int resolutionToSliderValue(int width) {
|
||||
switch (width) {
|
||||
case 1024:
|
||||
return -3;
|
||||
case 1280:
|
||||
return -2;
|
||||
case 1600:
|
||||
return -1;
|
||||
case 2560:
|
||||
return 1;
|
||||
case 3200:
|
||||
return 2;
|
||||
case 4096:
|
||||
return 3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
late int _width;
|
||||
late int _height;
|
||||
}
|
||||
|
||||
class _ThemeSettings extends StatefulWidget {
|
||||
@override
|
||||
createState() => _ThemeSettingsState();
|
||||
|
|
|
@ -7,6 +7,7 @@ class StatefulSlider extends StatefulWidget {
|
|||
required this.initialValue,
|
||||
this.min = 0.0,
|
||||
this.max = 1.0,
|
||||
this.divisions,
|
||||
this.onChangeEnd,
|
||||
}) : super(key: key);
|
||||
|
||||
|
@ -16,6 +17,7 @@ class StatefulSlider extends StatefulWidget {
|
|||
final double initialValue;
|
||||
final double min;
|
||||
final double max;
|
||||
final int? divisions;
|
||||
final ValueChanged<double>? onChangeEnd;
|
||||
}
|
||||
|
||||
|
@ -32,6 +34,7 @@ class _StatefulSliderState extends State<StatefulSlider> {
|
|||
value: _value,
|
||||
min: widget.min,
|
||||
max: widget.max,
|
||||
divisions: widget.divisions,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_value = value;
|
||||
|
|
|
@ -23,6 +23,8 @@ class ImageProcessorChannelHandler(context: Context) :
|
|||
call.argument("fileUrl")!!,
|
||||
call.argument("headers"),
|
||||
call.argument("filename")!!,
|
||||
call.argument("maxWidth")!!,
|
||||
call.argument("maxHeight")!!,
|
||||
result
|
||||
)
|
||||
} catch (e: Throwable) {
|
||||
|
@ -36,6 +38,8 @@ class ImageProcessorChannelHandler(context: Context) :
|
|||
call.argument("fileUrl")!!,
|
||||
call.argument("headers"),
|
||||
call.argument("filename")!!,
|
||||
call.argument("maxWidth")!!,
|
||||
call.argument("maxHeight")!!,
|
||||
result
|
||||
)
|
||||
} catch (e: Throwable) {
|
||||
|
@ -57,23 +61,24 @@ class ImageProcessorChannelHandler(context: Context) :
|
|||
|
||||
private fun zeroDce(
|
||||
fileUrl: String, headers: Map<String, String>?, filename: String,
|
||||
result: MethodChannel.Result
|
||||
maxWidth: Int, maxHeight: Int, result: MethodChannel.Result
|
||||
) = method(
|
||||
fileUrl, headers, filename, ImageProcessorService.METHOD_ZERO_DCE,
|
||||
result
|
||||
fileUrl, headers, filename, maxWidth, maxHeight,
|
||||
ImageProcessorService.METHOD_ZERO_DCE, result
|
||||
)
|
||||
|
||||
private fun deepLab3Portrait(
|
||||
fileUrl: String, headers: Map<String, String>?, filename: String,
|
||||
result: MethodChannel.Result
|
||||
maxWidth: Int, maxHeight: Int, result: MethodChannel.Result
|
||||
) = method(
|
||||
fileUrl, headers, filename,
|
||||
fileUrl, headers, filename, maxWidth, maxHeight,
|
||||
ImageProcessorService.METHOD_DEEL_LAP_PORTRAIT, result
|
||||
)
|
||||
|
||||
private fun method(
|
||||
fileUrl: String, headers: Map<String, String>?, filename: String,
|
||||
method: String, result: MethodChannel.Result
|
||||
maxWidth: Int, maxHeight: Int, method: String,
|
||||
result: MethodChannel.Result
|
||||
) {
|
||||
val intent = Intent(context, ImageProcessorService::class.java).apply {
|
||||
putExtra(ImageProcessorService.EXTRA_METHOD, method)
|
||||
|
@ -82,6 +87,8 @@ class ImageProcessorChannelHandler(context: Context) :
|
|||
ImageProcessorService.EXTRA_HEADERS,
|
||||
headers?.let { HashMap(it) })
|
||||
putExtra(ImageProcessorService.EXTRA_FILENAME, filename)
|
||||
putExtra(ImageProcessorService.EXTRA_MAX_WIDTH, maxWidth)
|
||||
putExtra(ImageProcessorService.EXTRA_MAX_HEIGHT, maxHeight)
|
||||
}
|
||||
ContextCompat.startForegroundService(context, intent)
|
||||
result.success(null)
|
||||
|
|
|
@ -32,6 +32,8 @@ class ImageProcessorService : Service() {
|
|||
const val EXTRA_FILE_URL = "fileUrl"
|
||||
const val EXTRA_HEADERS = "headers"
|
||||
const val EXTRA_FILENAME = "filename"
|
||||
const val EXTRA_MAX_WIDTH = "maxWidth"
|
||||
const val EXTRA_MAX_HEIGHT = "maxHeight"
|
||||
|
||||
private const val ACTION_CANCEL = "cancel"
|
||||
|
||||
|
@ -100,7 +102,9 @@ class ImageProcessorService : Service() {
|
|||
Log.e(TAG, "Unknown method: $method")
|
||||
// we can't call stopSelf here as it'll stop the service even if
|
||||
// there are commands running in the bg
|
||||
addCommand(ImageProcessorCommand(startId, "null", "", null, ""))
|
||||
addCommand(
|
||||
ImageProcessorCommand(startId, "null", "", null, "", 0, 0)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,9 +129,11 @@ class ImageProcessorService : Service() {
|
|||
val headers =
|
||||
extras.getSerializable(EXTRA_HEADERS) as HashMap<String, String>?
|
||||
val filename = extras.getString(EXTRA_FILENAME)!!
|
||||
val maxWidth = extras.getInt(EXTRA_MAX_WIDTH)
|
||||
val maxHeight = extras.getInt(EXTRA_MAX_HEIGHT)
|
||||
addCommand(
|
||||
ImageProcessorCommand(
|
||||
startId, method, fileUrl, headers, filename
|
||||
startId, method, fileUrl, headers, filename, maxWidth, maxHeight
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -273,6 +279,8 @@ private data class ImageProcessorCommand(
|
|||
val fileUrl: String,
|
||||
val headers: Map<String, String>?,
|
||||
val filename: String,
|
||||
val maxWidth: Int,
|
||||
val maxHeight: Int,
|
||||
val args: Map<String, Any> = mapOf(),
|
||||
)
|
||||
|
||||
|
@ -412,11 +420,13 @@ private open class ImageProcessorCommandTask(context: Context) :
|
|||
return try {
|
||||
val fileUri = Uri.fromFile(file)
|
||||
val output = when (cmd.method) {
|
||||
ImageProcessorService.METHOD_ZERO_DCE -> ZeroDce(context).infer(
|
||||
ImageProcessorService.METHOD_ZERO_DCE -> ZeroDce(
|
||||
context, cmd.maxWidth, cmd.maxHeight
|
||||
).infer(
|
||||
fileUri
|
||||
)
|
||||
ImageProcessorService.METHOD_DEEL_LAP_PORTRAIT -> DeepLab3Portrait(
|
||||
context
|
||||
context, cmd.maxWidth, cmd.maxHeight
|
||||
).infer(fileUri)
|
||||
else -> throw IllegalArgumentException(
|
||||
"Unknown method: ${cmd.method}"
|
||||
|
|
|
@ -71,11 +71,9 @@ private class DeepLab3(context: Context) {
|
|||
private val context = context
|
||||
}
|
||||
|
||||
class DeepLab3Portrait(context: Context) {
|
||||
class DeepLab3Portrait(context: Context, maxWidth: Int, maxHeight: Int) {
|
||||
companion object {
|
||||
private const val RADIUS = 16
|
||||
private const val MAX_WIDTH = 2048
|
||||
private const val MAX_HEIGHT = 1536
|
||||
|
||||
private const val TAG = "DeepLab3Portrait"
|
||||
}
|
||||
|
@ -115,7 +113,7 @@ class DeepLab3Portrait(context: Context) {
|
|||
Log.i(TAG, "[enhance] Enhancing image")
|
||||
// downscale original to prevent OOM
|
||||
val orig = BitmapUtil.loadImage(
|
||||
context, imageUri, MAX_WIDTH, MAX_HEIGHT, BitmapResizeMethod.FIT,
|
||||
context, imageUri, maxWidth, maxHeight, BitmapResizeMethod.FIT,
|
||||
isAllowSwapSide = true, shouldUpscale = false
|
||||
)
|
||||
val bg = Toolkit.blur(orig, radius)
|
||||
|
@ -146,5 +144,7 @@ class DeepLab3Portrait(context: Context) {
|
|||
}
|
||||
|
||||
private val context = context
|
||||
private val maxWidth = maxWidth
|
||||
private val maxHeight = maxHeight
|
||||
private val deepLab = DeepLab3(context)
|
||||
}
|
||||
|
|
|
@ -10,16 +10,13 @@ import org.tensorflow.lite.Interpreter
|
|||
import java.nio.FloatBuffer
|
||||
import kotlin.math.pow
|
||||
|
||||
class ZeroDce(context: Context) {
|
||||
class ZeroDce(context: Context, maxWidth: Int, maxHeight: Int) {
|
||||
companion object {
|
||||
private const val TAG = "ZeroDce"
|
||||
private const val MODEL = "zero_dce_lite_200x300_iter8_60.tflite"
|
||||
private const val WIDTH = 300
|
||||
private const val HEIGHT = 200
|
||||
private const val ITERATION = 8
|
||||
|
||||
private const val MAX_WIDTH = 2048
|
||||
private const val MAX_HEIGHT = 1536
|
||||
}
|
||||
|
||||
fun infer(imageUri: Uri): Bitmap {
|
||||
|
@ -54,7 +51,7 @@ class ZeroDce(context: Context) {
|
|||
Log.i(TAG, "Enhancing image, iteration: $iteration")
|
||||
// downscale original to prevent OOM
|
||||
val resized = BitmapUtil.loadImage(
|
||||
context, imageUri, MAX_WIDTH, MAX_HEIGHT, BitmapResizeMethod.FIT,
|
||||
context, imageUri, maxWidth, maxHeight, BitmapResizeMethod.FIT,
|
||||
isAllowSwapSide = true, shouldUpscale = false
|
||||
)
|
||||
// resize aMaps
|
||||
|
@ -77,4 +74,6 @@ class ZeroDce(context: Context) {
|
|||
}
|
||||
|
||||
private val context = context
|
||||
private val maxWidth = maxWidth
|
||||
private val maxHeight = maxHeight
|
||||
}
|
||||
|
|
|
@ -6,24 +6,32 @@ import 'package:nc_photos_plugin/src/k.dart' as k;
|
|||
class ImageProcessor {
|
||||
static Future<void> zeroDce(
|
||||
String fileUrl,
|
||||
String filename, {
|
||||
String filename,
|
||||
int maxWidth,
|
||||
int maxHeight, {
|
||||
Map<String, String>? headers,
|
||||
}) =>
|
||||
_methodChannel.invokeMethod("zeroDce", <String, dynamic>{
|
||||
"fileUrl": fileUrl,
|
||||
"headers": headers,
|
||||
"filename": filename,
|
||||
"maxWidth": maxWidth,
|
||||
"maxHeight": maxHeight,
|
||||
});
|
||||
|
||||
static Future<void> deepLab3Portrait(
|
||||
String fileUrl,
|
||||
String filename, {
|
||||
String filename,
|
||||
int maxWidth,
|
||||
int maxHeight, {
|
||||
Map<String, String>? headers,
|
||||
}) =>
|
||||
_methodChannel.invokeMethod("deepLab3Portrait", <String, dynamic>{
|
||||
"fileUrl": fileUrl,
|
||||
"headers": headers,
|
||||
"filename": filename,
|
||||
"maxWidth": maxWidth,
|
||||
"maxHeight": maxHeight,
|
||||
});
|
||||
|
||||
static const _methodChannel =
|
||||
|
|
Loading…
Add table
Reference in a new issue