Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9703

ゲーム翻訳ツール

$
0
0
  サンプルコード GAS function doPost(e) { var a = [e.postData.getDataAsString(),'en','ja'] return ContentService.createTextOutput(LanguageApp.translate(...a)) } MainWindow.xaml.cs namespace Konjac{ public partial class MainWindow : Window{ public MainWindow(){ InitializeComponent(); webView.NavigationCompleted += (s, e) => { webView.CoreWebView2.AddHostObjectToScript("bridge", new Bridge(webView)); }; webView.Source = new Uri(GetPath() + "\\Konjac.html"); } private static string GetPath(){ var p = System.Diagnostics.Process.GetCurrentProcess(); return System.IO.Path.GetDirectoryName(p.MainModule.FileName); } } } Bridge.cs public class Native{ // DPI (PerMonitorV2) //https://msdn.microsoft.com/en-us/library/windows/desktop/dd145062(v=vs.85).aspx //https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx public const int WM_DPICHANGED = 0x02E0; [DllImport("User32.dll")] public static extern IntPtr MonitorFromPoint([In] Point pt, [In] uint dwFlags); [DllImport("Shcore.dll")] public static extern IntPtr GetDpiForMonitor([In] IntPtr hmonitor, [In] DpiType dpiType, [Out] out uint dpiX, [Out] out uint dpiY); public enum DpiType{ Effective = 0, Angular = 1, Raw = 2, } } public class ScreenData{ public uint dpi { get; set; } public Screen screen { get; set; } public ScreenData(Screen s){ var p = new Point(s.Bounds.Left + 1, s.Bounds.Top + 1); var m = Native.MonitorFromPoint(p, 2/*MONITOR_DEFAULTTONEAREST*/); uint x, y; Native.GetDpiForMonitor(m, Native.DpiType.Effective, out x, out y); screen = s; dpi = x; } } public class BridgeEvent{ public string type { get; set; } public string value { get; set; } public BridgeEvent(string t, string v){ type = t; value = v; } public string ToJson(){ return JsonSerializer.Serialize(this); } } [ComVisible(true)] public class Bridge{ Bitmap capture; WebView2 view; public Bridge(WebView2 w){ view = w; } public async void Scan(int x, int y, int w, int h){ Bitmap textBmp = new Bitmap(w, h); Graphics g = Graphics.FromImage(textBmp); g.DrawImage(capture, new Point(-x, -y)); g.Dispose(); string file = "Konjac.png"; string path = $"{GetPath()}\\{file}"; textBmp.Save(path); string s = await OCR(file); Console.WriteLine(s); var e = new BridgeEvent("SCAN_DONE", s); //jsからの非同期呼び出しでnullが返る //https://github.com/MicrosoftEdge/WebView2Feedback/issues/822 view.CoreWebView2.PostWebMessageAsString(e.ToJson()); } public async Task<string> OCR(string file){ //https://water2litter.net/rye/post/c_ocr_hello/ Stream input_stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read); var source = new WriteableBitmap(System.Windows.Media.Imaging.BitmapFrame.Create(input_stream)); input_stream.Close(); PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(source)); MemoryStream temp_stream = new MemoryStream(); encoder.Save(temp_stream); var converted_stream = WindowsRuntimeStreamExtensions.AsRandomAccessStream(temp_stream); var decorder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(converted_stream); SoftwareBitmap bitmap = await decorder.GetSoftwareBitmapAsync(); converted_stream.Dispose(); temp_stream.Close(); OcrEngine engine = OcrEngine.TryCreateFromLanguage(new Windows.Globalization.Language("en")); var result = await engine.RecognizeAsync(bitmap); return result.Text; } public string Post(string url, string data){ //https://docs.microsoft.com/ja-jp/dotnet/framework/network-programming/how-to-send-data-using-the-webrequest-class Console.WriteLine(url); byte[] byteArray = Encoding.UTF8.GetBytes(data); var request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = byteArray.Length; Stream dataStream = request.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); var response = (HttpWebResponse)request.GetResponse(); string responseContent = string.Empty; using (dataStream = response.GetResponseStream()) { StreamReader reader = new StreamReader(dataStream); string responseFromServer = reader.ReadToEnd(); Console.WriteLine(responseFromServer); response.Close(); return responseFromServer; } } public string CaptureScreen(int i){ Screen s = Screen.AllScreens[i]; capture = new Bitmap(s.Bounds.Width, s.Bounds.Height); Graphics g = Graphics.FromImage(capture); g.CopyFromScreen(new Point(s.Bounds.X, s.Bounds.Y), new Point(0, 0), capture.Size); g.Dispose(); string file = $"Screen{i}.png"; string path = $"{GetPath()}\\{file}"; Console.WriteLine(path); capture.Save(path); return file; } private static string GetPath(){ var p = System.Diagnostics.Process.GetCurrentProcess(); return Path.GetDirectoryName(p.MainModule.FileName); } public string getAllScreens(){ List<ScreenData> screens = new List<ScreenData>(); foreach (Screen s in Screen.AllScreens){ screens.Add(new ScreenData(s)); } return JsonSerializer.Serialize(screens); } } Konjac.html <!DOCTYPE html><html lang="ja"><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> DEPLOY_ID = '***************************' //GAS $(e=>{$('body').append(new Konjac().view)}) class Konjac{ constructor(){ Konjac.native = new Konjac.Bridge().ready(v=>{ v.getScreens(r=>{ this.item = r.map((v,i)=>new Konjac.Screen(v,i)) this.init() }) }) this.view = _html('.container') } init(){ this.currentItem = this.item[0] var screens = this.item.sort((a,b)=>{return a.x-b.x}) screens.forEach(v=>v.menuItem.click(e=>this.select(v))) this.view.append( _html('.content',screens.map(v=>v.view)), this.overlay = _html('.overlay').hide().click(e=>this.overlay.hide()), _html('.header', _html('ul',screens.map(v=>v.menuItem)), _html('.button,翻訳する').click(e=>{ this.overlay.empty().show() this.ocr() }) ), ) Konjac.native.hook.SCAN_DONE = e=>{ this.overlay.append(_html('.en',e.value)) this.translate(e.value,ja=>{ this.overlay.prepend(_html('.ja',ja)) }) } var g = new Konjac.Gamepad({ GAMEPAD_A:e=>this.rescan(), GAMEPAD_B:e=>{this.overlay.hide()} }) this.select(this.currentItem) } rescan(){ this.currentItem.capture(r=>{ this.overlay.empty().show() this.ocr() }) } select(item){ this.overlay.hide() this.currentItem = item this.item.forEach(v=>{ v.menuItem.removeClass('selected') v.view.hide() }) item.menuItem.addClass('selected') item.view.show() item.capture() } ocr(){ var dpr = this.currentItem.dpr var w = $(window) var rect = [ Math.round(w.scrollLeft()*dpr), Math.round(w.scrollTop()*dpr), Math.round(w.width()*dpr), Math.round((w.height()-$('.header').height())*dpr), ] Konjac.native.ocr(...rect) return this } translate(data,success){ var url = `https://script.google.com/macros/s/${DEPLOY_ID}/exec`; Konjac.native.post(url,data,v=>success(v)) return this } } Konjac.Gamepad = class KonjacGamepad{ constructor(hook){ var s = 'A,B,X,Y,LB,RB,LT,RT,BACK,START,LS,RS,UP,DOWN,LEFT,RIGHT,HOME' this.types = s.split(',').map(s=>'GAMEPAD_'+s) this.hook = hook this.stack = [] this.length = 0 window.addEventListener("gamepadconnected",e=>{ console.log(e) this.stack[e.gamepad.index] = [e.gamepad] this.length++ }); window.addEventListener("gamepaddisconnected",e=>{ console.log(e) this.stack[e.gamepad.index] = [] this.length-- }); setInterval(e=>this.loop(),1000/30) } loop(){ if(this.length==0) return var items = [...navigator.getGamepads()].filter(Boolean) if(items.length==0) return var a = this.stack[items[0].index] a.unshift(items[0]) a[0].buttons.forEach((b,i)=>{ if(b.pressed==true) return if(a[1].buttons[i].pressed==false) return this.dispatch(this.types[i]) }) this.stack[items[0].index] = a.slice(0,1) } dispatch(type){ console.log(type) if(this.hook[type]) this.hook[type]() } } Konjac.Screen = class KonjacScreen{ constructor(data,i){ var b = data.screen.Bounds var dpr = data.dpi/96 this.x = b.Left this.y = b.Top this.w = b.Width this.h = b.Height this.width = Math.round(b.Width/dpr) this.height = Math.round(b.Height/dpr) this.dpr = dpr//devicePixelRatio this.name = data.screen.DeviceName.replace(/[^\w\s]/g,'') this.index = i Object.assign(this,data) var s = b.Width+' x '+b.Height this.sizeText = Konjac.Screen.type[s]||s this.menuItem = _html('li',this.name,' ',_html('span',this.sizeText)) this.view = _html('img').css({width:this.width}) } capture(f){ Konjac.native.capture(this.index,r=>{ this.view.attr('src',r+'?'+Math.random()) if(f) f(r) }) return this } } Konjac.Screen.type = { '1920 x 1080':'FHD', '1920 x 1200':'WUXGA', '2560 x 1440':'WQHD', '3840 x 2160':'4K', } Konjac.Bridge = class KonjacBridge{ constructor(){ this.hook = {} this.on(()=>{}).ready(()=>{}) this.hostObjects = {bridge:{}} if(chrome.webview){ this.hostObjects = chrome.webview.hostObjects chrome.webview.addEventListener('message',e=>{ var data = JSON.parse(e.data) var hook = this.hook[data.type]||this.hook.on hook(data) }) } setTimeout(e=>this.hook.ready(this),100) } on(f){this.hook.on = f return this } ready(f){this.hook.ready = f return this } getScreens(f){ this.hostObjects.bridge.getAllScreens().then(r=>{ f(JSON.parse(r)) }).catch(console.log) return this } capture(i,f){ this.hostObjects.bridge.CaptureScreen(i).then(r=>f(r)) return this } ocr(...a){this.hostObjects.bridge.Scan(...a) return this } async post(url,data,success) { var result = await this.hostObjects.bridge.Post(url,data); success(result) } } function _html(...a){ var b = a.shift().split(',') var c = b.shift().split('.') var d = c.shift()||'div' return $(`<${d}>`).addClass(...c).append(...b,...a) } </script> <style> /* 略 */ </style></head></html>

Viewing all articles
Browse latest Browse all 9703

Trending Articles