You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
5.6 KiB
195 lines
5.6 KiB
import 'package:get/get.dart';
|
|
import '../../../data/services/language_manager.dart';
|
|
|
|
/// 图片翻译历史记录模型
|
|
class PictureTranslationHistory {
|
|
final String id;
|
|
final String imagePath;
|
|
final String sourceText;
|
|
final String translatedText;
|
|
final String sourceLanguageCode;
|
|
final String targetLanguageCode;
|
|
final DateTime timestamp;
|
|
final String? thumbnailPath; // 缩略图路径
|
|
|
|
PictureTranslationHistory({
|
|
required this.id,
|
|
required this.imagePath,
|
|
required this.sourceText,
|
|
required this.translatedText,
|
|
required this.sourceLanguageCode,
|
|
required this.targetLanguageCode,
|
|
required this.timestamp,
|
|
this.thumbnailPath,
|
|
});
|
|
|
|
/// 从JSON创建实例
|
|
factory PictureTranslationHistory.fromJson(Map<String, dynamic> json) {
|
|
return PictureTranslationHistory(
|
|
id: json['id'] ?? '',
|
|
imagePath: json['imagePath'] ?? '',
|
|
sourceText: json['sourceText'] ?? '',
|
|
translatedText: json['translatedText'] ?? '',
|
|
sourceLanguageCode: json['sourceLanguageCode'] ?? 'zh-CN',
|
|
targetLanguageCode: json['targetLanguageCode'] ?? 'en-US',
|
|
timestamp:
|
|
DateTime.parse(json['timestamp'] ?? DateTime.now().toIso8601String()),
|
|
thumbnailPath: json['thumbnailPath'],
|
|
);
|
|
}
|
|
|
|
/// 转换为JSON
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'id': id,
|
|
'imagePath': imagePath,
|
|
'sourceText': sourceText,
|
|
'translatedText': translatedText,
|
|
'sourceLanguageCode': sourceLanguageCode,
|
|
'targetLanguageCode': targetLanguageCode,
|
|
'timestamp': timestamp.toIso8601String(),
|
|
'thumbnailPath': thumbnailPath,
|
|
};
|
|
}
|
|
|
|
/// 获取源语言中文名称
|
|
String get sourceLanguageName {
|
|
final languageManager = Get.find<LanguageManager>();
|
|
return languageManager.getChineseNameByAsrCode(sourceLanguageCode) ??
|
|
'未知语言';
|
|
}
|
|
|
|
/// 获取目标语言中文名称
|
|
String get targetLanguageName {
|
|
final languageManager = Get.find<LanguageManager>();
|
|
return languageManager.getChineseNameByAsrCode(targetLanguageCode) ??
|
|
'未知语言';
|
|
}
|
|
|
|
/// 创建副本
|
|
PictureTranslationHistory copyWith({
|
|
String? id,
|
|
String? imagePath,
|
|
String? sourceText,
|
|
String? translatedText,
|
|
String? sourceLanguageCode,
|
|
String? targetLanguageCode,
|
|
DateTime? timestamp,
|
|
String? thumbnailPath,
|
|
}) {
|
|
return PictureTranslationHistory(
|
|
id: id ?? this.id,
|
|
imagePath: imagePath ?? this.imagePath,
|
|
sourceText: sourceText ?? this.sourceText,
|
|
translatedText: translatedText ?? this.translatedText,
|
|
sourceLanguageCode: sourceLanguageCode ?? this.sourceLanguageCode,
|
|
targetLanguageCode: targetLanguageCode ?? this.targetLanguageCode,
|
|
timestamp: timestamp ?? this.timestamp,
|
|
thumbnailPath: thumbnailPath ?? this.thumbnailPath,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 处理状态枚举
|
|
enum ProcessingStatus {
|
|
idle, // 空闲
|
|
picking, // 选择图片
|
|
recognizing, // 识别文本
|
|
translating, // 翻译文本
|
|
saving, // 保存记录
|
|
error, // 错误状态
|
|
}
|
|
|
|
/// 处理步骤信息
|
|
class ProcessingStep {
|
|
final String title;
|
|
final String description;
|
|
final ProcessingStatus status;
|
|
final double progress;
|
|
final String? error;
|
|
|
|
ProcessingStep({
|
|
required this.title,
|
|
required this.description,
|
|
required this.status,
|
|
this.progress = 0.0,
|
|
this.error,
|
|
});
|
|
|
|
ProcessingStep copyWith({
|
|
String? title,
|
|
String? description,
|
|
ProcessingStatus? status,
|
|
double? progress,
|
|
String? error,
|
|
}) {
|
|
return ProcessingStep(
|
|
title: title ?? this.title,
|
|
description: description ?? this.description,
|
|
status: status ?? this.status,
|
|
progress: progress ?? this.progress,
|
|
error: error ?? this.error,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 图片翻译返回的坐标点模型(用于文本块四个点)
|
|
class Point2D {
|
|
final int x;
|
|
final int y;
|
|
|
|
Point2D({required this.x, required this.y});
|
|
|
|
/// 从JSON创建
|
|
factory Point2D.fromJson(Map<String, dynamic> json) {
|
|
return Point2D(
|
|
x: (json['X'] ?? 0) as int,
|
|
y: (json['Y'] ?? 0) as int,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 图片翻译返回的文本块模型
|
|
class ImageTextBlock {
|
|
final List<Point2D> points; // 文本块四点坐标
|
|
final String detectedLanguage; // 检测到的语种
|
|
final String text; // 识别内容
|
|
final String translation; // 翻译结果
|
|
final List<int>? foreColor; // 文字平均色 RGBA
|
|
final List<int>? backColor; // 背景平均色 RGBA
|
|
|
|
ImageTextBlock({
|
|
required this.points,
|
|
required this.detectedLanguage,
|
|
required this.text,
|
|
required this.translation,
|
|
this.foreColor,
|
|
this.backColor,
|
|
});
|
|
|
|
/// 从JSON创建
|
|
factory ImageTextBlock.fromJson(Map<String, dynamic> json) {
|
|
final List<dynamic> pts = (json['Points'] ?? []) as List<dynamic>;
|
|
return ImageTextBlock(
|
|
points: pts.map((e) => Point2D.fromJson(e as Map<String, dynamic>)).toList(),
|
|
detectedLanguage: (json['DetectedLanguage'] ?? '') as String,
|
|
text: (json['Text'] ?? '') as String,
|
|
translation: (json['Translation'] ?? '') as String,
|
|
foreColor: (json['ForeColor'] as List?)?.map((e) => e as int).toList(),
|
|
backColor: (json['BackColor'] as List?)?.map((e) => e as int).toList(),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 图片翻译结果模型(包含回贴后的图片和文本块列表)
|
|
class ImageTranslationResult {
|
|
final List<int>? translatedImageBytes; // 回贴后的图片二进制(Uint8List)
|
|
final List<ImageTextBlock> blocks; // 文本块列表
|
|
final String? detectedLanguage; // 可选:整体检测到的语种
|
|
|
|
ImageTranslationResult({
|
|
required this.translatedImageBytes,
|
|
required this.blocks,
|
|
this.detectedLanguage,
|
|
});
|
|
}
|
|
|