Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-m-o committed Feb 1, 2024
2 parents 493daab + 35615d5 commit f16b252
Show file tree
Hide file tree
Showing 115 changed files with 14,404 additions and 5,247 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ copy_ppocr_build.bat
.vscode/c_cpp_properties.json
yomininja-e/.vscode/c_cpp_properties.json
yomininja-e/.vscode/settings.json
yomininja-e/electron-src/@core/infra/ocr/cloud_vision_ocr.adapter/test/test_data.ts
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ https://github.com/matt-m-o/YomiNinja/assets/25914763/2bb02444-fc41-44e7-bc9e-c6
https://github.com/matt-m-o/YomiNinja/assets/25914763/1868db47-5b50-44c1-a5b3-694d46c69e28


The extracted text overlays the original content, allowing for quick look-ups with pop-up dictionaries like [10ten](https://github.com/birchill/10ten-ja-reader) and [Yomichan](https://github.com/FooSoft/yomichan). <br>
The extracted text overlays the original content, allowing for quick look-ups with pop-up dictionaries like [10ten](https://github.com/birchill/10ten-ja-reader), [Yomichan](https://github.com/FooSoft/yomichan) and [Inkah](https://chromewebstore.google.com/detail/inkah-chinese-korean-pop/pcgmedbmchghfgikplcimdmfldfnecec). <br>
It minimizes distractions and simplifies the process of looking up unfamiliar words. <br>
This is especially beneficial for language learners who study through videos or games.

Expand Down Expand Up @@ -47,28 +47,30 @@ YomiNinja currently offers support for distros using the X11 window system. Wayl
```


### Install Yomichan (optional):
1. Install [Yomichan](https://foosoft.net/projects/yomichan/) on your browser of preference.
2. Go to the Yomichan settings.
### Install Yomichan or Yomitan (optional):
1. Install [Yomichan](https://foosoft.net/projects/yomichan/)/[Yomitan](https://github.com/themoeway/yomitan#installation) on your browser of preference.
2. Go to the Yomichan/Yomitan settings.
3. Find and enable the clipboard monitoring option.

- Chromium: `Enable background clipboard text monitoring`
- Firefox: `Enable native popups when copying Japanese text`
4. Go to the YomiNinja settings and enable ```Show Yomichan window on text copy```
4. Go to the YomiNinja settings and enable ```Show window on text copy```
5. Set the `Window title` to "Yomichan Search" or "Yomitan Search".


## Current features

- Text extraction from the entire screen or specific window.
- Built-in pop-up dictionaries.
- Chrome Extensions (partial support).
- OCR Templates (predefined text areas, optimizing OCR efficiency).
- WebSocket for Texthookers.


## Planned Features

- Text extraction from snip.
- OCR Templates (predefined text areas, optimizing OCR efficiency).
- Auto OCR.
- Text extraction from snip.
- Anki integration.
- History.
- Text translation.
Expand Down Expand Up @@ -101,15 +103,15 @@ It supports dozens of languages, that will be integrated into this application i

./yomininja-e/extensions/10ten

5. Install node modules. Note: `--force` is used due to outdated react-furi peerDependencies, but it should function normally.
4. Install node modules. Note: `--force` is used due to outdated react-furi peerDependencies, but it should function normally.
```commandline
cd yomininja-e && npm install --force
```
6. Generate gRPC Protobuf types
5. Generate gRPC Protobuf types
```commandline
npm run grpc-types
```
7. Build the distribution
6. Build the distribution
```commandline
npm run dist
```
Expand All @@ -121,5 +123,5 @@ It supports dozens of languages, that will be integrated into this application i

## Inspired by:
- [Yomichan](https://github.com/FooSoft/yomichan)
- [Manga OCR](https://github.com/kha-white/manga-ocr)
- [mokuro](https://github.com/kha-white/mokuro)
- [kanjitomo-ocr](https://github.com/sakarika/kanjitomo-ocr)
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,28 @@ export type ImageResizeOutput = {
resizedImage: Buffer;
width?: number;
height?: number;
};

export type ImageExtractInput = {
image: Buffer;
position: {
left: number;
top: number;
};
size: {
width: number;
height: number;
};
};

export type ImageMetadata = {
width: number;
height: number;
}

export interface ImageProcessingAdapter {
resize: ( input: ImageResizeInput ) => Promise< ImageResizeOutput >;
invertColors: ( imageBuffer: Buffer ) => Promise< Buffer >;
invertColors: ( image: Buffer ) => Promise< Buffer >;
extract: ( input: ImageExtractInput ) => Promise< Buffer >;
getMetadata: ( image: Buffer ) => Promise< ImageMetadata >;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { LanguageTypeOrmSchema } from "../../../infra/db/typeorm/language/langua
import ProfileTypeOrmRepository from "../../../infra/db/typeorm/profile/profile.typeorm.repository";
import { ChangeActiveLanguage_Input, ChangeActiveOcrLanguageUseCase } from "./change_active_ocr_language.use_case";
import LanguageTypeOrmRepository from "../../../infra/db/typeorm/language/language.typeorm.repository";
import { OcrTemplateTypeOrmSchema } from "../../../infra/db/typeorm/ocr_template/ocr_template.schema";
import { OcrTargetRegionTypeOrmSchema } from "../../../infra/db/typeorm/ocr_template/ocr_target_region/ocr_target_region.schema";

describe("ChangeActiveOcrLanguageUseCase tests", () => {

Expand All @@ -27,7 +29,9 @@ describe("ChangeActiveOcrLanguageUseCase tests", () => {
entities: [
ProfileTypeOrmSchema,
SettingsPresetTypeOrmSchema,
LanguageTypeOrmSchema
LanguageTypeOrmSchema,
OcrTemplateTypeOrmSchema,
OcrTargetRegionTypeOrmSchema
],
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { SettingsPreset } from "../../../domain/settings_preset/settings_preset";
import { DataSource } from 'typeorm';
import { Language } from "../../../domain/language/language";
import { Profile } from "../../../domain/profile/profile";
import { ProfileTypeOrmSchema } from "../../../infra/db/typeorm/profile/profile.schema";
import { SettingsPresetTypeOrmSchema } from "../../../infra/db/typeorm/settings_preset/settings_preset.schema";
import { LanguageTypeOrmSchema } from "../../../infra/db/typeorm/language/language.schema";
import ProfileTypeOrmRepository from "../../../infra/db/typeorm/profile/profile.typeorm.repository";
import LanguageTypeOrmRepository from "../../../infra/db/typeorm/language/language.typeorm.repository";
import { ChangeActiveOcrTemplateUseCase, ChangeActiveOcrTemplate_Input } from "./change_active_ocr_template.use_case";
import { OcrTemplateTypeOrmSchema } from "../../../infra/db/typeorm/ocr_template/ocr_template.schema";
import { OcrTargetRegionTypeOrmSchema } from "../../../infra/db/typeorm/ocr_template/ocr_target_region/ocr_target_region.schema";
import { OcrTemplate } from "../../../domain/ocr_template/ocr_template";
import OcrTemplateTypeOrmRepository from "../../../infra/db/typeorm/ocr_template/ocr_template.typeorm.repository";
import { OcrTargetRegion } from "../../../domain/ocr_template/ocr_target_region/ocr_target_region";

describe("ChangeActiveOcrTemplateUseCase tests", () => {

let changeActiveOcrTemplateUseCase: ChangeActiveOcrTemplateUseCase;

let initialProfile: Profile;

let profilesRepo: ProfileTypeOrmRepository;

let ocrTemplate: OcrTemplate;

beforeEach( async () => {

let dataSource = new DataSource({
type: 'sqlite',
database: ':memory:',
synchronize: true,
logging: false,
entities: [
ProfileTypeOrmSchema,
SettingsPresetTypeOrmSchema,
LanguageTypeOrmSchema,
OcrTemplateTypeOrmSchema,
OcrTargetRegionTypeOrmSchema
],
});

await dataSource.initialize();

const settingsPreset = SettingsPreset.create();
await dataSource.getRepository( SettingsPreset ).insert( settingsPreset );

const languageJa = Language.create({ name: 'japanese', two_letter_code: 'ja' });
await dataSource.getRepository( Language ).insert( languageJa );


const ocrTemplatesRepo = new OcrTemplateTypeOrmRepository(
dataSource.getRepository( OcrTemplate ),
dataSource.getRepository( OcrTargetRegion )
);
ocrTemplate = OcrTemplate.create({
name: 'Template 1',
image: Buffer.from('')
});
await ocrTemplatesRepo.insert( ocrTemplate );
ocrTemplate = await ocrTemplatesRepo.findOne({
id: ocrTemplate.id
}) as OcrTemplate;

profilesRepo = new ProfileTypeOrmRepository( dataSource.getRepository( Profile ) );


initialProfile = Profile.create({
active_ocr_language: languageJa,
active_settings_preset: settingsPreset,
});

await profilesRepo.insert( initialProfile );

changeActiveOcrTemplateUseCase = new ChangeActiveOcrTemplateUseCase({
profilesRepo,
ocrTemplatesRepo
});

});

it("should change the active ocr template from null to a ocr template", async () => {

const input: ChangeActiveOcrTemplate_Input = {
profileId: initialProfile.id,
ocrTemplateId: ocrTemplate.id
};

await changeActiveOcrTemplateUseCase.execute( input );

const currentProfile = await profilesRepo.findOne({ id: initialProfile.id });

expect( currentProfile?.active_ocr_template )
.toStrictEqual( ocrTemplate );
});


it("should change the active ocr template to null", async () => {

const input: ChangeActiveOcrTemplate_Input = {
profileId: initialProfile.id,
ocrTemplateId: null
};

await changeActiveOcrTemplateUseCase.execute( input );

const currentProfile = await profilesRepo.findOne({ id: initialProfile.id });

expect( currentProfile?.active_ocr_template )
.toStrictEqual( null );
});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Language } from "../../../domain/language/language";
import { LanguageRepository } from "../../../domain/language/language.repository";
import { OcrTemplate, OcrTemplateId } from "../../../domain/ocr_template/ocr_template";
import { OcrTemplateRepository } from "../../../domain/ocr_template/ocr_template.repository";
import { Profile } from "../../../domain/profile/profile";
import { ProfileRepository } from "../../../domain/profile/profile.repository";


export type ChangeActiveOcrTemplate_Input = {
ocrTemplateId: OcrTemplateId | null; // Two letters
profileId: string;
}

export class ChangeActiveOcrTemplateUseCase {

private profilesRepo: ProfileRepository;
private ocrTemplatesRepo: OcrTemplateRepository;

constructor( input: {
profilesRepo: ProfileRepository;
ocrTemplatesRepo: OcrTemplateRepository;
}) {
this.profilesRepo = input.profilesRepo;
this.ocrTemplatesRepo = input.ocrTemplatesRepo;
}

async execute( input: ChangeActiveOcrTemplate_Input ): Promise< OcrTemplate | null > {

let ocrTemplate: OcrTemplate | null = null;

if ( input?.ocrTemplateId ) {
ocrTemplate = await this.ocrTemplatesRepo.findOne({
id: input.ocrTemplateId,
});
}

const profile: Profile | null = await this.profilesRepo.findOne({
id: input.profileId
});

if ( !profile )
return null;

profile.active_ocr_template = ocrTemplate;

await this.profilesRepo.update( profile );

return ocrTemplate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Profile } from "../../../domain/profile/profile";
import { SettingsPreset } from "../../../domain/settings_preset/settings_preset";
import { SettingsPresetInMemoryRepository } from "../../../infra/db/in_memory/settings_preset/settings_preset.in_memory.repository";
import { LanguageTypeOrmSchema } from "../../../infra/db/typeorm/language/language.schema";
import { OcrTargetRegionTypeOrmSchema } from "../../../infra/db/typeorm/ocr_template/ocr_target_region/ocr_target_region.schema";
import { OcrTemplateTypeOrmSchema } from "../../../infra/db/typeorm/ocr_template/ocr_template.schema";
import { ProfileTypeOrmSchema } from "../../../infra/db/typeorm/profile/profile.schema";
import ProfileTypeOrmRepository from "../../../infra/db/typeorm/profile/profile.typeorm.repository";
import { SettingsPresetTypeOrmSchema } from "../../../infra/db/typeorm/settings_preset/settings_preset.schema";
Expand All @@ -28,7 +30,9 @@ describe("GetActiveSettingsPresetUseCase tests", () => {
entities: [
ProfileTypeOrmSchema,
SettingsPresetTypeOrmSchema,
LanguageTypeOrmSchema
LanguageTypeOrmSchema,
OcrTemplateTypeOrmSchema,
OcrTargetRegionTypeOrmSchema
],
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { SettingsPresetTypeOrmSchema } from "../../../infra/db/typeorm/settings_

import { DataSource } from 'typeorm';
import { GetProfileUseCase, GetProfile_Input } from "./get_profile.use_case";
import { OcrTemplateTypeOrmSchema } from "../../../infra/db/typeorm/ocr_template/ocr_template.schema";
import { OcrTargetRegionTypeOrmSchema } from "../../../infra/db/typeorm/ocr_template/ocr_target_region/ocr_target_region.schema";

describe("GetProfileUseCase tests", () => {

Expand All @@ -28,7 +30,9 @@ describe("GetProfileUseCase tests", () => {
entities: [
ProfileTypeOrmSchema,
SettingsPresetTypeOrmSchema,
LanguageTypeOrmSchema
LanguageTypeOrmSchema,
OcrTemplateTypeOrmSchema,
OcrTargetRegionTypeOrmSchema
],
});

Expand Down
Loading

0 comments on commit f16b252

Please sign in to comment.