AI 해상도: CPU 에서 자동이 만화용을 고르면 알리고 '사진' 모델로 바꿔 다시 할 수 있게
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>묶음3
parent
986688eafa
commit
300ccdde99
|
|
@ -39,6 +39,7 @@
|
||||||
"\"백그라운드로 실행\" 이 꺼져 있어 앱을 끝내면 작업이 멈춥니다.": "\"Run in background\" is off, so closing the app stops these tasks.",
|
"\"백그라운드로 실행\" 이 꺼져 있어 앱을 끝내면 작업이 멈춥니다.": "\"Run in background\" is off, so closing the app stops these tasks.",
|
||||||
"\"외부 브라우저로 열기\" 에 쓸 브라우저 (이 PC 에 설치된 것)": "Browser for \"Open in external browser\" (installed on this PC)",
|
"\"외부 브라우저로 열기\" 에 쓸 브라우저 (이 PC 에 설치된 것)": "Browser for \"Open in external browser\" (installed on this PC)",
|
||||||
"# Netscape HTTP Cookie File\n# JJ_MKVMaker 앱 안 브라우저에서 내보냄\n\n": "# Netscape HTTP Cookie File\n# Exported from the JJ_MKVMaker in-app browser\n\n",
|
"# Netscape HTTP Cookie File\n# JJ_MKVMaker 앱 안 브라우저에서 내보냄\n\n": "# Netscape HTTP Cookie File\n# Exported from the JJ_MKVMaker in-app browser\n\n",
|
||||||
|
"'사진' 모델로 바꿔 다시": "Switch to 'Photos' and redo",
|
||||||
"(AI 번역을 쓸 수 없는 기기라 언어를 더할 수 없습니다)": "(Languages cannot be added because AI translation is unavailable on this device)",
|
"(AI 번역을 쓸 수 없는 기기라 언어를 더할 수 없습니다)": "(Languages cannot be added because AI translation is unavailable on this device)",
|
||||||
"({0}개 지움)": "(delete {0})",
|
"({0}개 지움)": "(delete {0})",
|
||||||
"(동영상을 세 번 누르면 옮깁니다)": "(Tapping a video three times moves it)",
|
"(동영상을 세 번 누르면 옮깁니다)": "(Tapping a video three times moves it)",
|
||||||
|
|
@ -880,6 +881,7 @@
|
||||||
"사용자가 취소했습니다.": "Cancelled by the user.",
|
"사용자가 취소했습니다.": "Cancelled by the user.",
|
||||||
"사용할 수 있는 자막 사이트가 없습니다.": "No subtitle site is available.",
|
"사용할 수 있는 자막 사이트가 없습니다.": "No subtitle site is available.",
|
||||||
"사진": "Photos",
|
"사진": "Photos",
|
||||||
|
"사진에는 '사진' 모델이 더 낫지만, 이 기기 (그래픽카드 없음) 에서는 한 장에 약 20분 걸립니다.": "The 'Photos' model is better for photos, but on this device (no graphics card) it takes about 20 minutes per image.",
|
||||||
"삭제": "Delete",
|
"삭제": "Delete",
|
||||||
"삭제 (목록에서 제거)": "Delete (remove from list)",
|
"삭제 (목록에서 제거)": "Delete (remove from list)",
|
||||||
"삭제 (중지하고 받던 파일 삭제)": "Delete (stop and delete the partial file)",
|
"삭제 (중지하고 받던 파일 삭제)": "Delete (stop and delete the partial file)",
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
"\"백그라운드로 실행\" 이 꺼져 있어 앱을 끝내면 작업이 멈춥니다.": "「バックグラウンドで実行」がオフなので、アプリを終了すると作業が止まります。",
|
"\"백그라운드로 실행\" 이 꺼져 있어 앱을 끝내면 작업이 멈춥니다.": "「バックグラウンドで実行」がオフなので、アプリを終了すると作業が止まります。",
|
||||||
"\"외부 브라우저로 열기\" 에 쓸 브라우저 (이 PC 에 설치된 것)": "「外部ブラウザーで開く」に使うブラウザー(この PC にインストール済み)",
|
"\"외부 브라우저로 열기\" 에 쓸 브라우저 (이 PC 에 설치된 것)": "「外部ブラウザーで開く」に使うブラウザー(この PC にインストール済み)",
|
||||||
"# Netscape HTTP Cookie File\n# JJ_MKVMaker 앱 안 브라우저에서 내보냄\n\n": "# Netscape HTTP Cookie File\n# JJ_MKVMaker アプリ内ブラウザーから書き出し\n\n",
|
"# Netscape HTTP Cookie File\n# JJ_MKVMaker 앱 안 브라우저에서 내보냄\n\n": "# Netscape HTTP Cookie File\n# JJ_MKVMaker アプリ内ブラウザーから書き出し\n\n",
|
||||||
|
"'사진' 모델로 바꿔 다시": "「写真」モデルに変えてやり直す",
|
||||||
"(AI 번역을 쓸 수 없는 기기라 언어를 더할 수 없습니다)": "(この端末では AI 翻訳が使えないため言語を追加できません)",
|
"(AI 번역을 쓸 수 없는 기기라 언어를 더할 수 없습니다)": "(この端末では AI 翻訳が使えないため言語を追加できません)",
|
||||||
"({0}개 지움)": "({0} 個を削除)",
|
"({0}개 지움)": "({0} 個を削除)",
|
||||||
"(동영상을 세 번 누르면 옮깁니다)": "(動画を 3 回タップすると移動します)",
|
"(동영상을 세 번 누르면 옮깁니다)": "(動画を 3 回タップすると移動します)",
|
||||||
|
|
@ -880,6 +881,7 @@
|
||||||
"사용자가 취소했습니다.": "ユーザーがキャンセルしました。",
|
"사용자가 취소했습니다.": "ユーザーがキャンセルしました。",
|
||||||
"사용할 수 있는 자막 사이트가 없습니다.": "使用できる字幕サイトがありません。",
|
"사용할 수 있는 자막 사이트가 없습니다.": "使用できる字幕サイトがありません。",
|
||||||
"사진": "写真",
|
"사진": "写真",
|
||||||
|
"사진에는 '사진' 모델이 더 낫지만, 이 기기 (그래픽카드 없음) 에서는 한 장에 약 20분 걸립니다.": "写真には「写真」モデルが適していますが、この端末 (グラフィックカードなし) では 1 枚に約 20 分かかります。",
|
||||||
"삭제": "削除",
|
"삭제": "削除",
|
||||||
"삭제 (목록에서 제거)": "削除(リストから外す)",
|
"삭제 (목록에서 제거)": "削除(リストから外す)",
|
||||||
"삭제 (중지하고 받던 파일 삭제)": "削除(中止してダウンロード中のファイルを削除)",
|
"삭제 (중지하고 받던 파일 삭제)": "削除(中止してダウンロード中のファイルを削除)",
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
"\"백그라운드로 실행\" 이 꺼져 있어 앱을 끝내면 작업이 멈춥니다.": "“后台运行”已关闭,退出应用会停止这些任务。",
|
"\"백그라운드로 실행\" 이 꺼져 있어 앱을 끝내면 작업이 멈춥니다.": "“后台运行”已关闭,退出应用会停止这些任务。",
|
||||||
"\"외부 브라우저로 열기\" 에 쓸 브라우저 (이 PC 에 설치된 것)": "“在外部浏览器中打开”使用的浏览器(本机已安装)",
|
"\"외부 브라우저로 열기\" 에 쓸 브라우저 (이 PC 에 설치된 것)": "“在外部浏览器中打开”使用的浏览器(本机已安装)",
|
||||||
"# Netscape HTTP Cookie File\n# JJ_MKVMaker 앱 안 브라우저에서 내보냄\n\n": "# Netscape HTTP Cookie File\n# 从 JJ_MKVMaker 内置浏览器导出\n\n",
|
"# Netscape HTTP Cookie File\n# JJ_MKVMaker 앱 안 브라우저에서 내보냄\n\n": "# Netscape HTTP Cookie File\n# 从 JJ_MKVMaker 内置浏览器导出\n\n",
|
||||||
|
"'사진' 모델로 바꿔 다시": "改用“照片”模型重新处理",
|
||||||
"(AI 번역을 쓸 수 없는 기기라 언어를 더할 수 없습니다)": "(此设备无法使用 AI 翻译,因此无法添加语言)",
|
"(AI 번역을 쓸 수 없는 기기라 언어를 더할 수 없습니다)": "(此设备无法使用 AI 翻译,因此无法添加语言)",
|
||||||
"({0}개 지움)": "(删除 {0} 个)",
|
"({0}개 지움)": "(删除 {0} 个)",
|
||||||
"(동영상을 세 번 누르면 옮깁니다)": "(连按视频三次会移动它)",
|
"(동영상을 세 번 누르면 옮깁니다)": "(连按视频三次会移动它)",
|
||||||
|
|
@ -880,6 +881,7 @@
|
||||||
"사용자가 취소했습니다.": "用户已取消。",
|
"사용자가 취소했습니다.": "用户已取消。",
|
||||||
"사용할 수 있는 자막 사이트가 없습니다.": "没有可用的字幕网站。",
|
"사용할 수 있는 자막 사이트가 없습니다.": "没有可用的字幕网站。",
|
||||||
"사진": "照片",
|
"사진": "照片",
|
||||||
|
"사진에는 '사진' 모델이 더 낫지만, 이 기기 (그래픽카드 없음) 에서는 한 장에 약 20분 걸립니다.": "照片更适合使用“照片”模型,但在本设备 (无显卡) 上每张约需 20 分钟。",
|
||||||
"삭제": "删除",
|
"삭제": "删除",
|
||||||
"삭제 (목록에서 제거)": "删除(从列表中移除)",
|
"삭제 (목록에서 제거)": "删除(从列表中移除)",
|
||||||
"삭제 (중지하고 받던 파일 삭제)": "删除(停止并删除正在下载的文件)",
|
"삭제 (중지하고 받던 파일 삭제)": "删除(停止并删除正在下载的文件)",
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,12 @@ Uint8List _finish((Uint8List, int, int, int, String, int) a) {
|
||||||
/// 그림 한 장 올리기. [input] 은 이 기기의 파일 (ZIP · WebDAV 의 그림은 부르는 쪽이 임시 파일로).
|
/// 그림 한 장 올리기. [input] 은 이 기기의 파일 (ZIP · WebDAV 의 그림은 부르는 쪽이 임시 파일로).
|
||||||
/// 결과를 [save] 가 true 면 저장하고 그 경로를, 아니면 임시 파일 경로를 돌려준다 (비교해 보고 저장할 때).
|
/// 결과를 [save] 가 true 면 저장하고 그 경로를, 아니면 임시 파일 경로를 돌려준다 (비교해 보고 저장할 때).
|
||||||
class AiUpscaler {
|
class AiUpscaler {
|
||||||
AiUpscaler({required this.device, required this.modelPath});
|
AiUpscaler({required this.device, required this.modelPath, this.modelId = ''});
|
||||||
final SdDevice device;
|
final SdDevice device;
|
||||||
final String modelPath;
|
final String modelPath;
|
||||||
|
|
||||||
|
/// 카탈로그 id (자동이 CPU 에서 만화용을 골랐는지 알리려고)
|
||||||
|
final String modelId;
|
||||||
Process? _proc;
|
Process? _proc;
|
||||||
bool _cancelled = false;
|
bool _cancelled = false;
|
||||||
|
|
||||||
|
|
@ -139,5 +142,5 @@ Future<AiUpscaler?> prepareUpscaler(AiStore store, {required String modelSetting
|
||||||
final gpu = dev.backend != 'cpu';
|
final gpu = dev.backend != 'cpu';
|
||||||
final id = pickUpscaleModel(modelSetting, gpu: gpu);
|
final id = pickUpscaleModel(modelSetting, gpu: gpu);
|
||||||
if (!store.isInstalled(id)) return null;
|
if (!store.isInstalled(id)) return null;
|
||||||
return AiUpscaler(device: dev, modelPath: store.pathOf(aiFile(id)));
|
return AiUpscaler(device: dev, modelPath: store.pathOf(aiFile(id)), modelId: id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,9 @@ Future<String?> upscaleOne(BuildContext context, AppController c, {required Stri
|
||||||
if (up == null || !context.mounted) return null;
|
if (up == null || !context.mounted) return null;
|
||||||
final progress = ValueNotifier<double?>(null);
|
final progress = ValueNotifier<double?>(null);
|
||||||
var cancelled = false;
|
var cancelled = false;
|
||||||
|
var toPhoto = false;
|
||||||
|
// 관리자: CPU 뿐이라 자동이 만화용을 고르면 사진은 질감이 뭉개질 수 있다 - 알리고 바로 바꿀 수 있게
|
||||||
|
final cpuAnime = c.settings.aiUpModel == 'auto' && up.device.backend == 'cpu' && up.modelId == 'esrgan-anime6b';
|
||||||
final nav = Navigator.of(context);
|
final nav = Navigator.of(context);
|
||||||
unawaited(showDialog<void>(
|
unawaited(showDialog<void>(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
@ -84,6 +87,19 @@ Future<String?> upscaleOne(BuildContext context, AppController c, {required Stri
|
||||||
LinearProgressIndicator(value: v),
|
LinearProgressIndicator(value: v),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text(v == null ? tr('준비하는 중') : '${(v * 100).round()}%', style: const TextStyle(fontSize: 12)),
|
Text(v == null ? tr('준비하는 중') : '${(v * 100).round()}%', style: const TextStyle(fontSize: 12)),
|
||||||
|
if (cpuAnime) ...[
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(tr("사진에는 '사진' 모델이 더 낫지만, 이 기기 (그래픽카드 없음) 에서는 한 장에 약 20분 걸립니다."),
|
||||||
|
style: const TextStyle(fontSize: 12, color: JjColors.textDim)),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
toPhoto = true;
|
||||||
|
cancelled = true;
|
||||||
|
up.cancel();
|
||||||
|
},
|
||||||
|
child: Text(tr("'사진' 모델로 바꿔 다시")),
|
||||||
|
),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -107,6 +123,11 @@ Future<String?> upscaleOne(BuildContext context, AppController c, {required Stri
|
||||||
}
|
}
|
||||||
nav.pop(); // 진행 창
|
nav.pop(); // 진행 창
|
||||||
if (!context.mounted) return null;
|
if (!context.mounted) return null;
|
||||||
|
if (toPhoto) {
|
||||||
|
await c.updateSettings((x) => x.aiUpModel = 'photo');
|
||||||
|
if (!context.mounted) return null;
|
||||||
|
return upscaleOne(context, c, input: input, nameFrom: nameFrom, outDir: outDir);
|
||||||
|
}
|
||||||
if (four == null) {
|
if (four == null) {
|
||||||
if (!cancelled) ScaffoldMessenger.maybeOf(context)?.showSnackBar(SnackBar(content: Text('$error')));
|
if (!cancelled) ScaffoldMessenger.maybeOf(context)?.showSnackBar(SnackBar(content: Text('$error')));
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue