Coder Social home page Coder Social logo

kaku's Introduction

Kaku: 画 (かく) - stroke (of a kanji, etc.), picture, drawing

https://kaku.fuwafuwa.ca/

Kaku is a fast, powerful Japanese dictionary that stays on top of all your apps. It uses optical character recognition (OCR) technology to recognize kanji on the device screen for you (rather than the slowww tedious process of looking up individual characters manually), making it perfect for Japanese learners who want to study by reading raw manga, play untranslated games, and so on without the hassle of switching apps.

Get it on F-Droid Get it on Google Play

kaku's People

Contributors

0xbad1d3a5 avatar linsui avatar poussinou avatar shimizoki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kaku's Issues

[Feature request] Chinese support

I've been trying to find something like kaku for Chinese but to no avail.

Would it be difficult to release a separate app for Chinese? I would be glad to contribute to something like that.

Thanks!

Touch circle taken into scan

I don't know if there is any way to avoid that, but the circle which appears on touch after enabled in the devices developer settings is also taken into the scan of Kaku.
Screenshot_20230817-194504

(Developer Options > Input > Show touch)

Screenshot_20230817-194618

Revisit instant mode UI

We can probably automatically determine box size in instant mode so users wouldn't have to real with resizing a box. Investigate feasibility.

Similar app that does it: https://www.youtube.com/watch?v=5f5YRc_yRtA&feature=youtu.be

Kaku's interface will probably be slightly different since it still makes a lot of sense to have the InstantKanjiWindows show up for rapid correction, but the idea is the same.

DB access is slow

Might be able to use native SQLite to speed it up? Some untested SQLite code:

SELECT result.fkEntry_id, result.kanji_id, result.kanji, result.reading_id, result.reading, result.meaning_id, result.meaninggloss_id, result.gloss, result.readingrestriction_id, result.readingRestriction, meaningkanjirestriction.id AS meaningkanjirestriction_id, meaningkanjirestriction.kanjiRestriction
FROM (SELECT result.fkEntry_id, result.kanji_id, result.kanji, result.reading_id, result.reading, result.meaning_id, result.meaninggloss_id, result.gloss, readingrestriction.id AS readingrestriction_id, readingrestriction.readingRestriction
      FROM (SELECT result.fkEntry_id, result.kanji_id, result.kanji, result.reading_id, result.reading, result.meaning_id, meaninggloss.id AS meaninggloss_id, meaninggloss.gloss
            FROM (SELECT result.fkEntry_id, result.kanji_id, result.kanji, reading.id AS reading_id, reading.reading, result.meaning_id
                  FROM (SELECT kanji.fkEntry_id, kanji.id AS kanji_id, kanji.kanji, meaning.id AS meaning_id
                        FROM kanji
                        INNER JOIN meaning ON kanji.fkEntry_id = meaning.fkEntry_id
                        WHERE kanji.kanji LIKE '%') AS result
                  INNER JOIN reading ON reading.fkEntry_id = result.fkEntry_id) AS result
            INNER JOIN meaninggloss ON result.meaning_id = meaninggloss.fkMeaning_id
            GROUP BY meaninggloss_id) AS result
      LEFT JOIN readingrestriction ON result.reading_id = readingrestriction.fkReading_id) AS result
LEFT JOIN meaningkanjirestriction ON result.meaning_id = meaningkanjirestriction.fkMeaning_id
ORDER BY meaning_id

Options notification menu not responding on Android 10

Hello. I use an umidigi A7 Pro and it seems thet after the latest OTA update of the phone the capability to use Kaku's notification menu was broken because now I'm unable to use it. It doesn't respond anymore, I can't even close the app like this unless I force stop it.

Preventing capture window from viewing keyboard

I believe this would work but cannot currently build Kaku to test it myself. But adding these two flags to the capture window's WindowManager.LayoutParams should work:

WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

My reasoning for this is that because Kaku does not save any settings, it can get annoying to have to move or close the capture window to type something. Additionally, I use a popped out dictionary to look up words that Kaku was unable to parse (especially pure hiragana/katakana phrases) and the keyboard being under the capture window can quickly get annoying.

Kaku crashes when no kanji is detected by the OCR engine

LOG:

01-13 15:12:07.001 23231 23231 D ca.fuwafuwa.kaku.Ocr.OcrRunnable: NOTIFIED
01-13 15:12:07.002 23231 23258 D ca.fuwafuwa.kaku.Ocr.OcrRunnable: THREAD STOPPED WAITING
01-13 15:12:07.002 23231 23258 D ca.fuwafuwa.kaku.Ocr.OcrRunnable: X:1040 Y:1176 (267x129)
01-13 15:12:07.008 23231 23258 D ca.fuwafuwa.kaku.Ocr.OcrRunnable: Image Dimensions: 2560x1440
01-13 15:12:07.084 23231 23258 F libc    : Fatal signal 6 (SIGABRT), code -6 in tid 23258 (Thread-4)
01-13 15:12:07.084   256   256 W         : debuggerd: handling request: pid=23231 uid=10149 gid=10149 tid=23258
01-13 15:12:07.088 23330 23330 W debuggerd: type=1400 audit(0.0:576): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.088 23330 23330 W debuggerd: type=1400 audit(0.0:577): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.088 23330 23330 W debuggerd: type=1400 audit(0.0:578): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.095 23330 23330 W debuggerd: type=1400 audit(0.0:579): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.095 23330 23330 W debuggerd: type=1400 audit(0.0:580): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.095 23330 23330 W debuggerd: type=1400 audit(0.0:581): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.095 23330 23330 W debuggerd: type=1400 audit(0.0:582): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.095 23330 23330 W debuggerd: type=1400 audit(0.0:583): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.095 23330 23330 W debuggerd: type=1400 audit(0.0:584): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:585): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:586): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:587): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:588): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:589): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:590): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:591): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:592): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:593): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:594): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:595): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:596): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:597): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:598): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.098 23330 23330 W debuggerd: type=1400 audit(0.0:599): avc: denied { search } for name="ca.fuwafuwa.kaku" dev="mmcblk0p42" ino=432919 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
01-13 15:12:07.119 23330 23330 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-13 15:12:07.119 23330 23330 F DEBUG   : Build fingerprint: 'google/shamu/shamu:7.0/NBD91J/3318369:user/release-keys'
01-13 15:12:07.119 23330 23330 F DEBUG   : Revision: '0'
01-13 15:12:07.119 23330 23330 F DEBUG   : ABI: 'arm'
01-13 15:12:07.119 23330 23330 F DEBUG   : pid: 23231, tid: 23258, name: Thread-4  >>> ca.fuwafuwa.kaku <<<
01-13 15:12:07.119 23330 23330 F DEBUG   : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
01-13 15:12:07.119 23330 23330 F DEBUG   :     r0 00000000  r1 00005ada  r2 00000006  r3 00000008
01-13 15:12:07.119 23330 23330 F DEBUG   :     r4 8e0ff978  r5 00000006  r6 8e0ff920  r7 0000010c
01-13 15:12:07.119 23330 23330 F DEBUG   :     r8 00000002  r9 8e105ad0  sl 8e105ad0  fp 8ff31640
01-13 15:12:07.119 23330 23330 F DEBUG   :     ip 00000058  sp 8e0feee8  lr b0d0b517  pc b0d0dd80  cpsr 600b0010
01-13 15:12:07.129 23330 23330 F DEBUG   : 
01-13 15:12:07.129 23330 23330 F DEBUG   : backtrace:
01-13 15:12:07.129 23330 23330 F DEBUG   :     #00 pc 00049d80  /system/lib/libc.so (tgkill+12)
01-13 15:12:07.129 23330 23330 F DEBUG   :     #01 pc 00047513  /system/lib/libc.so (pthread_kill+34)
01-13 15:12:07.129 23330 23330 F DEBUG   :     #02 pc 0001d615  /system/lib/libc.so (raise+10)
01-13 15:12:07.129 23330 23330 F DEBUG   :     #03 pc 00019161  /system/lib/libc.so (__libc_android_abort+34)
01-13 15:12:07.129 23330 23330 F DEBUG   :     #04 pc 00017028  /system/lib/libc.so (abort+4)
01-13 15:12:07.129 23330 23330 F DEBUG   :     #05 pc 000e12f7  /data/app/ca.fuwafuwa.kaku-1/lib/arm/libtess.so (_ZNK7ERRCODE5errorEPKc16TessErrorLogCodeS1_z+170)
01-13 15:12:07.129 23330 23330 F DEBUG   :     #06 pc 000a4e25  /data/app/ca.fuwafuwa.kaku-1/lib/arm/libtess.so (_ZN9tesseract14ChoiceIteratorC1ERKNS_17LTRResultIteratorE+44)
01-13 15:12:07.129 23330 23330 F DEBUG   :     #07 pc 0017c1e5  /data/app/ca.fuwafuwa.kaku-1/lib/arm/libtess.so (Java_com_googlecode_tesseract_android_ResultIterator_nativeGetChoices+32)
01-13 15:12:07.129 23330 23330 F DEBUG   :     #08 pc 000097ff  /data/data/ca.fuwafuwa.kaku/cache/slice-com.rmtheis-tess-two-6.1.1_ff6eb97b1edc3dca0f1bfaf9c3c054e06e8b0054-classes.dex (offset 0x10000)
01-13 15:12:08.079   829   850 I BootReceiver: Copying /data/tombstones/tombstone_05 to DropBox (SYSTEM_TOMBSTONE)
01-13 15:12:08.082   256   256 W         : debuggerd: resuming target 23231
01-13 15:12:08.132   829 10241 I VirtualDisplayAdapter: Virtual display device released because application token died: ca.fuwafuwa.kaku
01-13 15:12:08.132   829 10242 D GraphicsStats: Buffer count: 8
01-13 15:12:08.132   283   283 I Adreno  : DequeueBuffer: dequeueBuffer failed
01-13 15:12:08.133   829   853 I DisplayManagerService: Display device removed: DisplayDeviceInfo{"ca.fuwafuwa.kaku.MainService": uniqueId="virtual:ca.fuwafuwa.kaku,10149,ca.fuwafuwa.kaku.MainService,0", 2560 x 1440, modeId 30, defaultModeId 30, supportedModes [{id=30, width=2560, height=1440, fps=60.0}], colorTransformId 0, defaultColorTransformId 0, supportedColorTransforms [], HdrCapabilities null, density 560, 560.0 x 560.0 dpi, appVsyncOff 0, presDeadline 16666666, touch NONE, rotation 0, type VIRTUAL, state ON, owner ca.fuwafuwa.kaku (uid 10149), FLAG_PRESENTATION}
01-13 15:12:08.133   283   283 E DisplayDevice: eglSwapBuffers(0x1, 0xa74b6b60) failed with 0x0000300d
01-13 15:12:08.133   283   283 I Adreno  : flush reason set to EsxFlushModeReasonInvalidBinLayout
01-13 15:12:08.133   283   283 I Adreno  : flush reason set to EsxFlushModeReasonInvalidBinLayout
01-13 15:12:08.135   829  6652 I ActivityManager: Process ca.fuwafuwa.kaku (pid 23231) has died
01-13 15:12:08.135   829  6652 D ActivityManager: cleanUpApplicationRecord -- 23231
01-13 15:12:08.135   829  6652 W ActivityManager: Scheduling restart of crashed service ca.fuwafuwa.kaku/.MainService in 1000ms
01-13 15:12:08.138   829   853 W DisplayManagerService: Failed to notify process 23231 that displays changed, assuming it died.
01-13 15:12:08.138   829   853 W DisplayManagerService: android.os.DeadObjectException
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at android.os.BinderProxy.transactNative(Native Method)
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at android.os.BinderProxy.transact(Binder.java:615)
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at android.hardware.display.IDisplayManagerCallback$Stub$Proxy.onDisplayEvent(IDisplayManagerCallback.java:81)
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at com.android.server.display.DisplayManagerService$CallbackRecord.notifyDisplayEventAsync(DisplayManagerService.java:1166)
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at com.android.server.display.DisplayManagerService.deliverDisplayEvent(DisplayManagerService.java:1004)
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at com.android.server.display.DisplayManagerService.-wrap6(DisplayManagerService.java)
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at com.android.server.display.DisplayManagerService$DisplayManagerHandler.handleMessage(DisplayManagerService.java:1099)
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at android.os.Handler.dispatchMessage(Handler.java:102)
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at android.os.Looper.loop(Looper.java:154)
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at android.os.HandlerThread.run(HandlerThread.java:61)
01-13 15:12:08.138   829   853 W DisplayManagerService: 	at com.android.server.ServiceThread.run(ServiceThread.java:46)
01-13 15:12:08.138   283   283 W libEGL  : EGLNativeWindowType 0xa7383008 disconnect failed
01-13 15:12:08.147   829  1303 W InputDispatcher: channel 'f787c61 ca.fuwafuwa.kaku (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
01-13 15:12:08.147   829  1303 E InputDispatcher: channel 'f787c61 ca.fuwafuwa.kaku (server)' ~ Channel is unrecoverably broken and will be disposed!
01-13 15:12:08.147   829  1303 W InputDispatcher: channel 'e7b7447 ca.fuwafuwa.kaku (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
01-13 15:12:08.147   829  1303 E InputDispatcher: channel 'e7b7447 ca.fuwafuwa.kaku (server)' ~ Channel is unrecoverably broken and will be disposed!
01-13 15:12:08.148   298   298 I Zygote  : Process 23231 exited due to signal (6)
01-13 15:12:08.163   829 10239 I WindowManager: WIN DEATH: Window{f787c61 u0 ca.fuwafuwa.kaku}
01-13 15:12:08.163   829 10239 W InputDispatcher: Attempted to unregister already unregistered input channel 'f787c61 ca.fuwafuwa.kaku (server)'
01-13 15:12:08.163   829  9340 I OpenGLRenderer: Initialized EGL, version 1.4
01-13 15:12:08.163   829  9340 D OpenGLRenderer: Swap behavior 1
01-13 15:12:08.163   829 10239 I WindowManager: Destroying surface Surface(name=) called by com.android.server.wm.WindowStateAnimator.destroySurface:2014 com.android.server.wm.WindowStateAnimator.destroySurfaceLocked:881 com.android.server.wm.WindowState.removeLocked:1449 com.android.server.wm.WindowManagerService.removeWindowInnerLocked:2478 com.android.server.wm.WindowManagerService.removeWindowLocked:2436 com.android.server.wm.WindowState$DeathRecipient.binderDied:1780 android.os.BinderProxy.sendDeathNotice:688 <bottom of call stack> 
01-13 15:12:08.168   829 10244 I WindowManager: WIN DEATH: Window{e7b7447 u0 ca.fuwafuwa.kaku}
01-13 15:12:08.168   829 10244 W InputDispatcher: Attempted to unregister already unregistered input channel 'e7b7447 ca.fuwafuwa.kaku (server)'
01-13 15:12:08.249 23261 23281 E epsxe   :  * Frame per second (33) - Time 60 frames -> 1.778 seconds.
01-13 15:12:08.369  1849 20556 W ContentTaskController: Invalid newTask was provided to startTracking.
01-13 15:12:08.616   829   853 I WindowManager: Destroying surface Surface(name=) called by com.android.server.wm.WindowStateAnimator.destroySurface:2014 com.android.server.wm.WindowStateAnimator.destroySurfaceLocked:881 com.android.server.wm.WindowState.destroyOrSaveSurface:2073 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementInner:429 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop:232 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement:180 com.android.server.wm.WindowManagerService$H.handleMessage:8079 android.os.Handler.dispatchMessage:102 
01-13 15:12:08.755 23261 23281 E epsxe   :  * Frame per second (118) - Time 60 frames -> 0.506 seconds.

Screenshot:
screenshot_20170113-152156

App disappears from home screen on update

This happens almost every time there's an update, but it only seems to occur with this app. I have to re-add the shortcut to my home screen or whatever every time the app updates. Luckily it leaves a nice gaping hole where it used to be so I don't forget where it was.

Investigate out of bounds in EditWindow.setInfo()

java.lang.IllegalArgumentException:
at android.graphics.Bitmap.checkPixelAccess (Bitmap.java:2021)
at android.graphics.Bitmap.setPixel (Bitmap.java:2088)
at ca.fuwafuwa.kaku.Windows.EditWindow.setInfo (EditWindow.kt:134)
at ca.fuwafuwa.kaku.Windows.Views.KanjiCharacterView.onTouchEvent (KanjiCharacterView.kt:164)
at android.view.View.dispatchTouchEvent (View.java:12555)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3153)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2829)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3159)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2844)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3159)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2844)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3159)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2844)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3159)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2844)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3159)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2844)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3159)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2844)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3159)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2844)
at android.view.View.dispatchPointerEvent (View.java:12803)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent (ViewRootImpl.java:5707)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess (ViewRootImpl.java:5502)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:4995)
at android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:5048)
at android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:5014)
at android.view.ViewRootImpl$AsyncInputStage.forward (ViewRootImpl.java:5151)
at android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:5022)
at android.view.ViewRootImpl$AsyncInputStage.apply (ViewRootImpl.java:5208)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:4995)
at android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:5048)
at android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:5014)
at android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:5022)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:4995)
at android.view.ViewRootImpl.deliverInputEvent (ViewRootImpl.java:7852)
at android.view.ViewRootImpl.doProcessInputEvents (ViewRootImpl.java:7792)
at android.view.ViewRootImpl.enqueueInputEvent (ViewRootImpl.java:7753)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent (ViewRootImpl.java:7963)
at android.view.InputEventReceiver.dispatchInputEvent (InputEventReceiver.java:197)
at android.os.MessageQueue.nativePollOnce (Native Method)
at android.os.MessageQueue.next (MessageQueue.java:325)
at android.os.Looper.loop (Looper.java:142)
at android.app.ActivityThread.main (ActivityThread.java:6942)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:327)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)

Finding the OCR box isn't robust enough to handle all Android display modes

We crash a lot when we can't find the OCR box, which happens due to the navigation bar / status bar, and apps being able to show & hide them and what not. It's especially annoying since if you rotate the device, the navigation bar does not rotate on a phone but does on a tablet. We may need to find a way to simply be able to quickly find the a exact sub-image from any image so that we aren't relying on the fragile logic of adding and subtracting status & navigation bar heights.

Candidates:

EPWING support

Allow users to change the dictionary used to an EPWING, or somehow integrate lookups with EBPocket or Droidwing.
OCR Manga Reader for Android has this feature, so its source code might 参考になります。

Since individual words can't be copied-and-pasted unless only one word is selected, and EBPocket and Droidwing don't support conjugation (although the OCR Manga Reader does, so I imagine it's implementable), there are a lot of reasons it's very painful to switch apps to look up words right now, especially when you intend to copy the full sentence for Anki; and since Kaku is apparently not intended to be used while switching apps. (see #20 )

Auto detection of speech bubbles to select text

It'd be great if auto-detection of speech bubbles in manga could be implemented. Capture2Text for PC has a similar functionality where if you press a hotkey whilst having your cursor hovering over a speech bubble of a manga, it auto detects the text inside and copies it. It even detects connected speech bubbles with two separate blobs of text.
I think it would make reading MT'led manga very convenient.

Option to move results box location

Having something like an option to allow the results window to show up in the bottom left instead, or for the app to automatically choose where to display depending on where the selection box is, would be nice for usability.

My hands are apparently too small to work well with modern phones, especially Galaxy S7-size phones (iPhone 5s was a stretch); and I'm a guy, so I can only image how hard girls must have it. I need to reaaally reach (or use two hands) whenever I need to tap the top/bottom left of my screen. In Kaku, the box shows up at the top left, so sometimes if I'm using the phone one-handed, I need to tap the top left to look up the first word in the results.

Unfortunately, no matter how carefully I try to tap (no doubt causing long-term damage in my right hand/thumb when I stretch like that...SCREW THIS LARGE PHONE TREND, I WANT iPHONE 4 SIZE AGAIN), the slightest bit of skin ends up touching the right side of the screen, instantly hiding the results window. So, Kaku is unusable for me when I am using the phone one-handed and try to select the first word in the results.

(By the way, I have a Galaxy S7, so as long as the app still works, I'll be happy, since I, and probably a lot of other people too, won't be getting Android Q on my current phone.)

Enhance image before sending to Tesseract for better OCR accuracy

@Shimizoki graciously sent over some otsu thresholding code in Java that should clean up the image a little:

    @Override
    public void run() {
                // ...
                long startTimeBitmap = System.currentTimeMillis();
                Bitmap gray = ColorToGrayscale(mBitmap);
                mBitmap = OtsuThreshold(gray).copy(Bitmap.Config.ARGB_8888, true);
                Log.d(TAG, String.format("Bitmap processing took: %d", System.currentTimeMillis() - startTimeBitmap));
    }

    public static Bitmap ColorToGrayscale(Bitmap bm) {
        Bitmap grayScale = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.RGB_565);

        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);

        Paint p = new Paint();
        p.setColorFilter(new ColorMatrixColorFilter(cm));

        new Canvas(grayScale).drawBitmap(bm, 0, 0, p);

        return grayScale;
    }

    public static Bitmap GrayscaleToBin(Bitmap bm, int threshold) {
        Bitmap bin = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.RGB_565);

        ColorMatrix cm = new ColorMatrix(new float[] {
                85.f, 85.f, 85.f, 0.f, -255.f * threshold,
                85.f, 85.f, 85.f, 0.f, -255.f * threshold,
                85.f, 85.f, 85.f, 0.f, -255.f * threshold,
                0f, 0f, 0f, 1f, 0f
        });

        Paint p = new Paint();
        p.setColorFilter(new ColorMatrixColorFilter(cm));

        new Canvas(bin).drawBitmap(bm, 0, 0, p);

        return bin;
    }

    public static Bitmap OtsuThreshold (Bitmap bm) {

        // Get Histogram
        int[] histogram = new int[256];
        for(int i = 0; i < histogram.length; i++) histogram[i] = 0;

        for(int i = 0; i < bm.getWidth(); i++) {
            for(int j = 0; j < bm.getHeight(); j++) {
                histogram[(bm.getPixel(i, j) & 0xFF0000) >> 16]++;
            }
        }

        // Get binary threshold using Otsu's method

        int total = bm.getHeight() * bm.getWidth();

        float sum = 0;
        for(int i = 0; i < 256; i++) sum += i * histogram[i];

        float sumB = 0;
        int wB = 0;
        int wF = 0;

        float varMax = 0;
        int threshold = 0;

        for(int i = 0 ; i < 256 ; i++) {
            wB += histogram[i];
            if(wB == 0) continue;
            wF = total - wB;

            if(wF == 0) break;

            sumB += (float) (i * histogram[i]);
            float mB = sumB / wB;
            float mF = (sum - sumB) / wF;

            float varBetween = (float)wB * (float)wF * (mB - mF) * (mB - mF);

            if(varBetween > varMax) {
                varMax = varBetween;
                threshold = i;
            }
        }

        return GrayscaleToBin(bm, threshold);
    }

I didn't have time to test for accuracy, but here's performance roughly (Axon 7):

D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: X:37 Y:1287 (1340x155)
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: Image Dimensions: 1440x2560
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: /storage/emulated/0/Android/data/ca.fuwafuwa.kaku/files/screenshots/screen 865587004995899.png
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: Bitmap processing took: 221
I/art: Do partial code cache collection, code=112KB, data=100KB
I/art: After code cache collection, code=112KB, data=100KB
I/art: Increasing code cache capacity to 512KB
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: THREAD STARTING NEW LOOP
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: WAITING
E/ca.fuwafuwa.kaku.MainServiceHandler: `[01/10/2017]でれたのしいができる
                                       Screenshot Time: 44
                                       OcrTime: 3549

D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: X:26 Y:858 (1379x1121)
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: Image Dimensions: 1440x2560
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: /storage/emulated/0/Android/data/ca.fuwafuwa.kaku/files/screenshots/screen 865598380184636.png
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: Bitmap processing took: 1400
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: THREAD STARTING NEW LOOP
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: WAITING
E/ca.fuwafuwa.kaku.MainServiceHandler: フィリピンでは19、のマラでのおりがあります。いキリストのをせたがのをります。このにると、がるなどの「がある」とわれています。によると、のおりには150ぐらいがしました。のが、にるためにの〈へこうとしました。にることができないためヽのにいるにオルをげるもいました。げたオルでにってもらってヽそのオルをのなどにします。フィリピンのによるとヽこのおりで10O0ぐらいがけがをしたりヽさでが〈なったりしました。
                                       Screenshot Time: 50
                                       OcrTime: 17896
                                       
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: X:26 Y:858 (1389x277)
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: Image Dimensions: 1440x2560
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: /storage/emulated/0/Android/data/ca.fuwafuwa.kaku/files/screenshots/screen 865653288799533.png
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: Bitmap processing took: 354
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: THREAD STARTING NEW LOOP
D/ca.fuwafuwa.kaku.Ocr.OcrRunnable: WAITING
E/ca.fuwafuwa.kaku.MainServiceHandler: フィリピンでは19、のマラでのおりがあります。いキリストのをせたがのをります。このにると、がるなどの「がある」とわれています。
                                       Screenshot Time: 40
                                       OcrTime: 4826

For now, I don't think I'll be committing this code though - rather than a quick fix now I'd rather wait until a good image processing pipeline can be designed and implemented. It seems like Tesseract already uses the Otsu method for binarizing images so I don't think this method would be the most effective way to process the capture either.

Leptonica, which is also in the tess-two library also seems to have some nice image processing functions we might be able to take advantage of (also runs in C so should be faster than a Java implementation).

https://groups.google.com/forum/#!topic/tesseract-ocr/JRwIz3xL45U

Fix commonly misrecognized kana, always provide ten-ten/small kana in swap quick action

Requesting:

  • kana always be given their ゛・゜options
  • 〈 and < either being given the option for く, or else always being corrected to く with the option to switch back
  • somehow fixing the problem with リ and こ being split into two characters (especially in the case of vertical writing?) like a comma and a pipe or something

Other common errors that aren't problematic:

  • し is interpreted as L, but at least you can correct it to し

Other issues will be reported here

Ankidroid integration via custom URL scheme

Related: #18 #19 #20

References:

Since there are Anki addons that add J-J definitions, and copying text is useful for (among other things) creating Ankidroid cards, and because switching apps closes the results window, cutting out the middle man and adding Ankidroid integration via a custom url scheme would be extremely helpful.

Desired features:

  • Sending entire text to Ankidroid as the "Sentence"
  • Sending a screenshot of the text without the result window, possible croppable, to Ankidroid. This can actually just be done by the user before OCR'in, and then they can add most recent screenshot when the card is created, so it's not necessary.
  • Sending the 原形/citation/dictionary form of the clicked-on/currently-highlighted word to Anki as the "Expression"
  • A definition (using the current dictionary, which is probably at this stage going to be English)
  • An option in the settings to specify which fields are actually exported, since different people will want different things.

Clear Build Instructions

I'd like to try experimenting with adding some of my own features into the app but can't quite figure out how to get it to build after a clone, but I saw the last comment on the matter was from an old issue in 2019. Any updates/modern instructions on building this?

not detecting words

I looked up the word 搾取する and it came up exactly like that in the ocr but it only detects the first kanji. also I dont see a way to copy the whole text to clipboard.

Music/Media pauses or stops when Kaku first opens

Apps like DoubleTwist will pause when Kaku opens, and apps like TuneIn Radio will stop streaming and need to be rebuffered before they start again. Don't remember the effects on VLC Media Player, but all media stops in some form on all apps.

Hiragana-only words do not show up in the dictionary

ぼうし(帽子)、けわしい(険しい)、うわさ(噂), and conjugated hiragana words can't be selected/aren't detected in the results window. I'm guessing if there's a kanji form, even if the kana form is common enough that it's written in kana in books for kids (as opposed to written in 漢字+振りがな), it won't be found in the dictionary.

F-Droid release states it's the Beta build

I'm not sure if this is on purpose, but the "Hello, 画 Beta User!" screen appears in the F-Droid build. It says to contact the developer if I'm seeing it unexpectedly.

[Bug Report/Feature request] Support for Boox devices

Thanks for all your effort developing Kaku. It seems like it isn't compatible with Boox devices since the popup isn't shown.
Resizing the window works but there is no content shown when tapping in the frame.

I use a Boox Poke 3 with Android 10, I use the Playstore version from the 9th May.

Porting to iPhone

Do you think it would be possible to port to iPhone/iOS? Maybe by making use of accessibility APIs

serious problem of innacuracy

90% of the time it gets the wrong result, it's almost impossible to use.
There's a project in which they used a manga dataset to train the model and it worked great.

https://github.com/kha-white/manga-ocr

i wonder if kaku could use that model or use the dataset to train a specifc model to be used in the app.

Support debug build from a fresh clone

It would be nice to clone the repo and get a successful build without running into multiple issues. Some of these might just be caused by my unfamiliarity with the source. I was going to try and add hiragana vocabulary recognition with a greedy match algorithm in the search class, but maybe you've already tried that.

On an unrelated note, would you be open to an F-Droid build flavor that doesn't include gms or any other proprietary libraries?

  1. Gradle won't sync when keystore.properties is missing.
  2. Google Ads will crash since the key is missing from strings.
  3. All image assets seem to be missing which broke the build.
  4. Tesseract will crash without the tessdata directory.
  5. The jpn training data also seems to be gone from the assets.

That's as far as I got before creating this issue.

Lock window resize

Related: #12

Since having the perfect window size/position is key (especially when dealing with hurigana), and when moving the window around there's a risk of accidentally resizing the window, it'd be nice to have an option (perhaps in the swipedown menu) to lock the window in its current shape.

Unable to stop TessBaseAPI from completing recognition

I think I know the cause here.

/** Make a text string from the internal data structures. */
char* TessBaseAPI::GetUTF8Text() {
  if (tesseract_ == NULL ||
      (!recognition_done_ && Recognize(NULL) < 0))
    return NULL;
  STRING text("");
  ResultIterator *it = GetIterator();
  do {
    if (it->Empty(RIL_PARA)) continue;
    char *para_text = it->GetUTF8Text(RIL_PARA);
    text += para_text;
    delete []para_text;
  } while (it->Next(RIL_PARA));
  char* result = new char[text.length() + 1];
  strncpy(result, text.string(), text.length() + 1);
  delete it;
  return result;
}

The GetUTF8Text() function in tesseract does not pass a monitor to Recognize, so recognition will never be canceled and will always block.

F-Droid distribution

Have you considered distributing Kaku on https://f-droid.org/ ?

I saw the dialog about valuing users privacy & etc., if you aren't familiar with F-Droid - I'm not an android developer but - it seem's to take users freedoms seriously. There is the #fdroid-dev channel on freenode if you use IRC, for help if necessary.

Confusing loading state in Battery Saver

Dear developer,

I noticed that when I enable Battery Saver on Android 8.1, the indeterminate ProgressBars in the app are not properly shown. This is a known problem in Android API level <28, see e.g. this StackOverflow question. Battery Saver disables animations, also on progress bars on these versions. This is quite confusing because the loading state is not properly represented. It is fixed in later Android versions, where progress bars do appear and animate.

Looking at the code, indeterminate progress bars are created here:

className='ca.fuwafuwa.kaku.MainStartFragment', lineNumber=144

To fix this issue, one can check ValueAnimator.areAnimatorsEnabled() and provide a different UI element, such as a text label, when animations are disabled.

I also recorded a video, showing the issue in practice:

ca.fuwafuwa.kaku.mov

Full selected text not available for copying

In normal (non-instant) mode, Kaku used to at least allow you to copy the entire selection of text, by performing OCR on the whole thing, even if it didn't have space to display the full result. I'd like this feature back in some form so that I can copy sentences to create Anki cards.

Shutting down Kaku's service does not completely kill the service

Not sure if this is just Android behavior or not with services. But onDestroy does get called and I'm pretty sure I'm disposing of every object properly. Regardless, this is causing us to leak a little bit of memory each time this happens. After 40+ open/close cycles in rapid succession it starts to affect system performance.

Force stopping the Kaku service through Android's Apps screen / service screen will reclaim lost memory and return performance back to normal on the device though.

Auto share on copy text

Requesting the ability to have an option in the settings for automatically sharing text when it's copied.

Right now part of my workflow consists of copying the text and then shaking my phone to open a fast sharing app (Fliktu) that replaces the default and opens almost immediately, but it's not only an extra step, it's also finicky. I figure people copy things for sharing (whether to have it get sent to Google translate or some other app), so I imagine a lot of people would value this. For me it would just cut out the work and uncertainty with sharing. For some reason if Fliktu doesn't work the first time on some copied text, I have to copy some other text (not the same text) before it'll start working again, almost as if it doesn't want to annoy users by working on the same text...even if you copy it again...which makes it unreliable on top of time consuming. This isn't a bug with Kaku, but anyway it'd be a really handy time-saving feature that makes a lot of sense and probably could be implemented in 20 minutes.

QS Tile

Start kaku upon pressing a qs tile button. :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.