Skip to content

Commit d5aabc0

Browse files
authored
Merge pull request #121 from killkimno/1.300v
1.302 업데이트
2 parents 94ae65e + d08ccd9 commit d5aabc0

File tree

7 files changed

+144
-37
lines changed

7 files changed

+144
-37
lines changed

MORT/OcrApi/OneOcr/NativeMethods.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,9 @@ static partial class NativeMethods
8585
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
8686
public static partial long CreateOcrPipeline(string modelPath, string key, long ctx, out long pipeline);
8787

88+
[LibraryImport("oneocr.dll", EntryPoint = "CreateOcrPipeline", StringMarshalling = StringMarshalling.Utf16)]
89+
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
90+
public static partial long CreateOcrPipeline_Utf16(string modelPath, string key, long ctx, out long pipeline);
91+
8892
}
8993
}

MORT/OcrApi/OneOcr/OneOcr.cs

Lines changed: 113 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,43 @@ public void CopyDll(string path)
6464
Console.WriteLine(ex.Message);
6565
}
6666
}
67-
67+
6868
public async ValueTask InitalizeAsync()
6969
{
7070
if(_initalized)
7171
{
7272
return;
7373
}
7474

75-
var scketch = await GetInstallLocation("Microsoft.ScreenSketch").ConfigureAwait(false);
76-
if(!string.IsNullOrEmpty(scketch))
75+
try
7776
{
78-
var path = Path.Combine(scketch, "SnippingTool");
79-
if(File.Exists(Path.Combine(path, "oneocr.dll")))
77+
if(!File.Exists(Path.Combine(OneOcrPath, OneOcrDll)))
8078
{
81-
CopyDll(path);
79+
var scketch = await GetInstallLocation("Microsoft.ScreenSketch").ConfigureAwait(false);
80+
if(!string.IsNullOrEmpty(scketch))
81+
{
82+
var path = Path.Combine(scketch, "SnippingTool");
83+
if(File.Exists(Path.Combine(path, "oneocr.dll")))
84+
{
85+
CopyDll(path);
86+
}
87+
}
88+
else
89+
{
90+
var photo = await GetInstallLocation("Microsoft.Windows.Photos").ConfigureAwait(false);
91+
if(File.Exists(Path.Combine(photo, "oneocr.dll")))
92+
{
93+
CopyDll(photo);
94+
}
95+
}
8296
}
8397
}
98+
catch
99+
{
100+
IsAvailable = false;
101+
return;
102+
}
103+
84104

85105
// Model key and path
86106
string key = "kj)TGtrK>f]b[Piow.gU+nC@s\"\"\"\"\"\"4";
@@ -89,25 +109,26 @@ public async ValueTask InitalizeAsync()
89109

90110
var ctx = Context;
91111
Console.WriteLine($"OneOcr DLL Path: {modelPath}");
92-
// Create OCR pipeline
93-
long res = NativeMethods.CreateOcrPipeline(modelPath, key, ctx, out long pipeline);
94-
if(res != 0)
112+
113+
// Create OCR pipeline — 여러 방식으로 시도하는 안전한 폴백 사용
114+
if(!TryCreateOcrPipelineWithFallback(modelPath, key, ctx, out long pipeline, out var pipelineDetails))
95115
{
96-
var msg = $"CreateOcrPipeline failed. res={res}, modelPath={modelPath}, dllPath={OneOcrPath}";
116+
var msg = $"CreateOcrPipeline failed. modelPath={modelPath}, dllPath={OneOcrPath}\nDetails: {pipelineDetails}";
97117
Console.Error.WriteLine(msg);
98118
Debug.WriteLine(msg);
119+
System.Windows.Forms.MessageBox.Show($"oneocr 초기화 실패:\n{pipelineDetails}");
99120
return;
100121
}
101122

102123
// Set process options
103-
res = NativeMethods.CreateOcrProcessOptions(out long opt);
124+
long res = NativeMethods.CreateOcrProcessOptions(out long opt);
104125
if(res != 0)
105126
{
106127
var msg = $"CreateOcrProcessOptions failed. res={res}";
107128
Console.Error.WriteLine(msg);
108129
Debug.WriteLine(msg);
109130
// try to cleanup pipeline if needed (if native provides)
110-
return ;
131+
return;
111132
}
112133

113134
res = NativeMethods.OcrProcessOptionsSetMaxRecognitionLineCount(opt, 1000);
@@ -122,8 +143,86 @@ public async ValueTask InitalizeAsync()
122143
_pipeline = pipeline;
123144
_opt = opt;
124145
_initalized = true;
146+
IsAvailable = true;
125147
}
126148

149+
// OneOcr 클래스 내부에 추가할 헬퍼 (UTF-8 -> UTF-16 -> 임시 ASCII 복사 순으로 시도)
150+
private bool TryCreateOcrPipelineWithFallback(string modelPath, string key, long ctx, out long pipeline, out string details)
151+
{
152+
pipeline = 0;
153+
details = "";
154+
try
155+
{
156+
// 1) 기존 자동생성(UTF-8) 시도
157+
try
158+
{
159+
long r = NativeMethods.CreateOcrPipeline(modelPath, key, ctx, out pipeline);
160+
details += $"Utf8 returned {r}";
161+
if(r == 0) return true;
162+
}
163+
catch(Exception ex)
164+
{
165+
details += $"Utf8 ex: {ex.GetType().Name}:{ex.Message}";
166+
}
167+
168+
// 2) UTF-16 오버로드 시도 (추가한 CreateOcrPipeline_Utf16)
169+
try
170+
{
171+
long r = NativeMethods.CreateOcrPipeline_Utf16(modelPath, key, ctx, out pipeline);
172+
details += " | Utf16 returned " + r;
173+
if(r == 0) return true;
174+
}
175+
catch(Exception ex)
176+
{
177+
details += " | Utf16 ex: " + ex.GetType().Name + ":" + ex.Message;
178+
}
179+
180+
// 3) 우회: 모델 파일을 ASCII-only 임시 경로로 복사해 재시도
181+
try
182+
{
183+
string tempDir = Path.Combine(Path.GetTempPath(), "oneocr_model");
184+
Directory.CreateDirectory(tempDir);
185+
string ext = Path.GetExtension(modelPath);
186+
string tmpFile = Path.Combine(tempDir, "oneocr_model_" + Guid.NewGuid().ToString("N") + ext);
187+
188+
File.Copy(modelPath, tmpFile, true);
189+
190+
try
191+
{
192+
long r = NativeMethods.CreateOcrPipeline(tmpFile, key, ctx, out pipeline);
193+
details += " | Copy->Utf8 returned " + r;
194+
if(r == 0) return true;
195+
}
196+
catch(Exception ex)
197+
{
198+
details += " | Copy->Utf8 ex: " + ex.GetType().Name + ":" + ex.Message;
199+
}
200+
201+
try
202+
{
203+
long r = NativeMethods.CreateOcrPipeline_Utf16(tmpFile, key, ctx, out pipeline);
204+
details += " | Copy->Utf16 returned " + r;
205+
if(r == 0) return true;
206+
}
207+
catch(Exception ex)
208+
{
209+
details += " | Copy->Utf16 ex: " + ex.GetType().Name + ":" + ex.Message;
210+
}
211+
}
212+
catch(Exception ex)
213+
{
214+
details += " | Copy failed: " + ex.GetType().Name + ":" + ex.Message;
215+
}
216+
}
217+
catch(Exception ex)
218+
{
219+
details += " | Unexpected: " + ex.GetType().Name + ":" + ex.Message;
220+
}
221+
222+
return false;
223+
}
224+
225+
127226
private static async ValueTask<string?> GetInstallLocation(string appName)
128227
{
129228
var info = new ProcessStartInfo("powershell.exe", $"-Command \"(Get-AppxPackage -Name {appName}).InstallLocation\"")
@@ -149,7 +248,7 @@ public async ValueTask InitalizeAsync()
149248
return path;
150249
}
151250

152-
251+
153252
private Line[] RunOcr(Img img)
154253
{
155254
try
@@ -393,7 +492,7 @@ public async ValueTask<Line[]> ConvertToTextAsync(byte[] byteData, int channel,
393492

394493
if(!IsAvailable)
395494
{
396-
// 필요시 null 반환 (기존 동작과 동일하게 유지)
495+
return null;
397496
}
398497

399498
Bitmap bitmap = null;

MORT/Properties/Settings.Designer.cs

Lines changed: 5 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MORT/Properties/Settings.settings

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
<Profiles />
44
<Settings>
55
<Setting Name="MORT_VERSION" Type="System.String" Scope="Application">
6-
<Value Profile="(Default)">1.301V</Value>
6+
<Value Profile="(Default)">1.302V</Value>
77
</Setting>
88
<Setting Name="LAYER_TEXT" Type="System.String" Scope="Application">
99
<Value Profile="(Default)">MORT {0}
1010
레이어 번역창</Value>
1111
</Setting>
1212
<Setting Name="MORT_VERSION_VALUE" Type="System.Int32" Scope="Application">
13-
<Value Profile="(Default)">1301</Value>
13+
<Value Profile="(Default)">1302</Value>
1414
</Setting>
1515
<Setting Name="TOOLTIP_LIST" Type="System.String" Scope="Application">
1616
<Value Profile="(Default)">MORT를 처음 쓰시면 그 외-&gt; MORT 사용법을 확인해 주세요,
@@ -45,11 +45,10 @@ OCR 영역을 빠르게 추가하고 싶을 땐 빠른 OCR 영역을 사용하
4545
구글 OCR의 사용량은 실제 사용량과 다를 수 있습니다. 수시로 구글 콘솔에서 확인하셔야 합니다</Value>
4646
</Setting>
4747
<Setting Name="MORT_RELEASE" Type="System.String" Scope="Application">
48-
<Value Profile="(Default)">2025 12 01</Value>
48+
<Value Profile="(Default)">2025 12 03</Value>
4949
</Setting>
5050
<Setting Name="BASIC_TEXT" Type="System.String" Scope="Application">
51-
<Value Profile="(Default)">
52-
Monkeyhead's OCR Realtime TransLate {0}
51+
<Value Profile="(Default)">Monkeyhead's OCR Realtime TransLate {0}
5352
제작자 : 몽키해드
5453
로고제작 : 김마손
5554
블로그 :

MORT/Resources/localize.csv

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,9 @@ Você pode definir a tela arrastando a tela no estado de configuração da área
605605
[Rehber] Gelişmiş ayarlardan sistem tepsisine küçültecek şekilde değiştirebilirsiniz"
606606
,Close App Title,종료하시겠습니까?,Would you like to end?,終わらせたいですか?,你想退出吗?,Apakah Anda ingin mengakhiri?,Хотели бы вы закончить?,Você gostaria de terminar?,"Ви впевнені, що хочете вийти?",Sonlandırmak ister misiniz?
607607
,Google Ocr Realtime Error,구글 OCR은 실시간 번역을 지원하지 않습니다. 스냅샷을 이용해 주세요,Google OCR does not support real -time translation. Please use a snapshot,Google OCRは、実際の翻訳をサポートしていません。スナップショットを使用してください,Google OCR不支持实时翻译,请使用截屏,Google OCR tidak mendukung terjemahan nyata -waktu. Silakan gunakan snapshot,"Google OCR не поддерживает реального перевода. Пожалуйста, используйте снимок","O Google OCR não suporta a tradução real de tempo. Por favor, use um instantâneo","Google OCR не підтримує переклад у реальному часі, будь ласка, використовуйте знімки",Google OCR gerçek zamanlı çeviriyi desteklemez. Lütfen bir anlık görüntü kullanın
608-
,Unable Use OCR Snipping Tool OCR Error,현재 사용할 수 없습니다. 다른 OCR 타입을 사용해 주세요,Currently unavailable. Please use a different OCR type.,現在利用できません。他のOCRタイプを使用してください,目前不可用。请使用其他OCR识别类型。,Saat ini tidak tersedia. Silakan gunakan jenis OCR yang berbeda.,В настоящее время недоступно. Используйте другой тип OCR.,"Atualmente indisponível. Por favor, utilize um tipo de OCR diferente.","Наразі недоступно. Будь ласка, скористайтеся іншим типом OCR.",Şu anda mevcut değil. Lütfen farklı bir OCR türü kullanın.
608+
,Unable Use OCR Snipping Tool OCR Error,"현재 사용할 수 없습니다. 다른 OCR 타입을 사용해 주세요.
609+
사용 방법을 확인해 보시겠습니까?",This feature is currently unavailable. Please use a different OCR type. Would you like to learn how to use it?,"現在利用できません。他のOCRタイプを使用してください。
610+
使い方を確認してみませんか?",此功能目前不可用。请使用其他OCR类型。您想了解如何使用吗?,Fitur ini saat ini tidak tersedia. Silakan gunakan jenis OCR yang berbeda. Ingin tahu cara menggunakannya?,"Эта функция сейчас недоступна. Используйте другой тип OCR. Хотите узнать, как ею пользоваться?","Este recurso está indisponível no momento. Por favor, utilize um tipo de OCR diferente. Gostaria de aprender a usá-lo?","Ця функція наразі недоступна. Будь ласка, скористайтеся іншим типом OCR. Бажаєте дізнатися, як ним користуватися?",Şu anda mevcut değil. Lütfen farklı bir OCR türü kullanın.
609611
,SnapShot Time Out,타임 아웃 - 스냅샷 후 번역할 창을 선택해 주세요,Time Out -Please select a translation window after snapshot,タイムアウト - スナップショットの後に翻訳ウィンドウを選択してください,超时 - 请选择一个窗口,在快照后进行翻译,Time out -Please Pilih jendela terjemahan setelah snapshot,"Time Out -Пожалуйста, выберите окно перевода после снимка","Tempo out -Por favor, selecione uma janela de tradução após o instantâneo","Тайм-аут - будь ласка, виберіть вікно для перекладу після знімка",Zaman aşımı - Lütfen anlık görüntüden sonra bir çeviri penceresi seçin
610612
,Translate Start,번역 시작,Beginning translation,翻訳を開始,开始翻译,Terjemahan awal,Начальный перевод,Tradução inicial,Почати переклад,Çeviriye başlanıyor
611613
,Translate Start Error,"OCR 영역이 없기 때문에 번역할 수 없습니다

MORT/Service/ProcessTranslateService/ProcessTranslateService.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -679,9 +679,9 @@ private async Task DoTrans(OcrMethodType ocrMethodType)
679679

680680
_winOcr.StartMakeBitmap();
681681
imgDataList[j].Clear();
682-
_winOcr.ProcessOCR();
683-
684-
682+
_winOcr.ProcessOCR();
683+
684+
685685
while(!isEndFlag && !_winOcr.GetIsAvailable())
686686
{
687687
Thread.Sleep(2);
@@ -749,14 +749,19 @@ private async Task DoTrans(OcrMethodType ocrMethodType)
749749
Util.CheckTimeSpan(false);
750750

751751
var task = _oneOcr.ConvertToTextAsync(imgDataList[j].data, imgDataList[j].channels, imgDataList[j].x, imgDataList[j].y, imgDataList[j].Clear).ConfigureAwait(false);
752-
752+
753753
var result = task.GetAwaiter().GetResult();
754754
if(result == null)
755755
{
756756
// 백그라운드에서 UI를 직접 호출하지 않음. UI 스레드에서 알리고 종료 트리거.
757757
_parent.BeginInvoke((Action)(() =>
758758
{
759-
MessageBox.Show(LocalizeString("Unable Use OCR Snipping Tool OCR Error"));
759+
if(MessageBox.Show(LocalizeString("Unable Use OCR Snipping Tool OCR Error"), "", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
760+
{
761+
762+
Util.OpenURL("https://blog.naver.com/killkimno/224097385261");
763+
}
764+
760765
OnStopTranslate?.Invoke(true);
761766
}));
762767

@@ -1118,7 +1123,7 @@ public void StopTranslate()
11181123
thread = null;
11191124
}
11201125

1121-
1126+
11221127
isEndFlag = false;
11231128
}
11241129

MORT/app.config

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,14 @@
7373
<applicationSettings>
7474
<MORT.Properties.Settings>
7575
<setting name="MORT_VERSION" serializeAs="String">
76-
<value>1.301V</value>
76+
<value>1.302V</value>
7777
</setting>
7878
<setting name="LAYER_TEXT" serializeAs="String">
7979
<value>MORT {0}
8080
레이어 번역창</value>
8181
</setting>
8282
<setting name="MORT_VERSION_VALUE" serializeAs="String">
83-
<value>1301</value>
83+
<value>1302</value>
8484
</setting>
8585
<setting name="TOOLTIP_LIST" serializeAs="String">
8686
<value>MORT를 처음 쓰시면 그 외-&gt; MORT 사용법을 확인해 주세요,
@@ -115,11 +115,10 @@ OCR 영역을 빠르게 추가하고 싶을 땐 빠른 OCR 영역을 사용하
115115
구글 OCR의 사용량은 실제 사용량과 다를 수 있습니다. 수시로 구글 콘솔에서 확인하셔야 합니다</value>
116116
</setting>
117117
<setting name="MORT_RELEASE" serializeAs="String">
118-
<value>2025 12 01</value>
118+
<value>2025 12 03</value>
119119
</setting>
120120
<setting name="BASIC_TEXT" serializeAs="String">
121-
<value>
122-
Monkeyhead's OCR Realtime TransLate {0}
121+
<value>Monkeyhead's OCR Realtime TransLate {0}
123122
제작자 : 몽키해드
124123
로고제작 : 김마손
125124
블로그 :

0 commit comments

Comments
 (0)