[Huawei Developers] John Wo:
More articles like this, you can visit HUAWEI Developer Forum and Medium​

Background

I believe that we all start to learn a language when we have done dictation, now when the primary school students learn the language is an important after - school work is dictating the text of the new words, many parents have this experience. However, on the one hand, the pronunciation is relatively simple. On the other hand, parents' time is very precious. Now, there are many dictation voices in the market. These broadcasters record the dictation words in the language teaching materials after class for parents to download. However, this kind of recording is not flexible enough, if the teacher leaves a few extra words today that are not part of the after-school problem set, the recordings won't meet the needs of parents and children. This document describes how to use the general text recognition and speech synthesis functions of the ML kit to implement the automatic voice broadcast app. You only need to take photos of dictation words or texts, and then the text in the photos can be automatically played. The tone color and tone of the voice can be adjusted.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/024/145/995/5190044000024145995.20200429075054.10040128706233039805294595890278:50510630065726:2800:2BB0905E0C399B8F533FE84A55F5BE323E6692771316D751F9F3499E0A78976F.jpg"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/024/145/995/5190044000024145995.20200429075054.10040128706233039805294595890278:50510630065726:2800:2BB0905E0C399B8F533FE84A55F5BE323E6692771316D751F9F3499E0A78976F.jpg[/IMG]

Development Preparations

Open the project-level build.gradle file

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/034/238/374/5190001000034238374.20200624063752.62398521025056406846780924853394:50510630055936:2800:425420EAC833B21F29D5CCFC4138C8EE4DADA6CCFC72AA1106B77968D6EFAC2A.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/034/238/374/5190001000034238374.20200624063752.62398521025056406846780924853394:50510630055936:2800:425420EAC833B21F29D5CCFC4138C8EE4DADA6CCFC72AA1106B77968D6EFAC2A.png[/IMG]

Choose allprojects > repositories and configure the Maven repository address of HMS SDK.

allprojects {
repositories {
google()
jcenter()
maven {url 'http://developer.huawei.com/repo/'}
}
}

Configure the Maven repository address of HMS SDK in buildscript->repositories.

buildscript {
repositories {
google()
jcenter()
maven {url 'http://developer.huawei.com/repo/'}
}
}

Choose buildscript > dependencies and configure the AGC plug-in.

dependencies {
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
}

Adding Compilation Dependencies

Open the application levelbuild.gradle file.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/034/238/374/5190001000034238374.20200624063819.36555625536468755893716957164333:50510630055936:2800:2DF7B9E49DF4C5938C63ECD332DC7E4F5E8AC12E25C916C62F4D16BFC77D02FC.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/034/238/374/5190001000034238374.20200624063819.36555625536468755893716957164333:50510630055936:2800:2DF7B9E49DF4C5938C63ECD332DC7E4F5E8AC12E25C916C62F4D16BFC77D02FC.png[/IMG]

SDK integration

dependencies{
implementation 'com.huawei.hms:ml-computer-voice-tts:1.0.4.300'
implementation 'com.huawei.hms:ml-computer-vision-ocr:1.0.4.300'
implementation 'com.huawei.hms:ml-computer-vision-ocr-cn-model:1.0.4.300'
}

Add the ACG plug-in to the file header.

apply plugin: 'com.huawei.agconnect'

Specify permissions and features: Declare them in AndroidManifest.xml.

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

Key Development Steps

There are two main functions. One is to identify the operation text, and the other is to read the operation. The OCR+TTS mode is used to read the operation. After taking a photo, click the play button to read the operation.

Dynamic permission application

private static final int PERMISSION_REQUESTS = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
// Checking camera permission
if (!allPermissionsGranted()) {
getRuntimePermissions();
}
}

2. Start the reading interface.

public void takePhoto(View view) {
Intent intent = new Intent(MainActivity.this, ReadPhotoActivity.class);
startActivity(intent);
}

3.Invoke createLocalTextAnalyzer() in the onCreate() method to create a device-side text recognizer.

private void createLocalTextAnalyzer() {
MLLocalTextSetting setting = new MLLocalTextSetting.Factory()
.setOCRMode(MLLocalTextSetting.OCR_DETECT_MODE)
.setLanguage("zh")
.create();
this.textAnalyzer = MLAnalyzerFactory.getInstance().getLocalTextAnalyzer(setting);

}

4.Invoke createLocalTextAnalyzer() in the onCreate() method to create a device-side text recognizer.

private void createTtsEngine() {
MLTtsConfig mlConfigs = new MLTtsConfig()
.setLanguage(MLTtsConstants.TTS_ZH_HANS)
.setPerson(MLTtsConstants.TTS_SPEAKER_FEMALE_ZH)
.setSpeed(0.2f)
.setVolume(1.0f);
this.mlTtsEngine = new MLTtsEngine(mlConfigs);
MLTtsCallback callback = new MLTtsCallback() {
@Override
public void onError(String taskId, MLTtsError err) {
}

@Override
public void onWarn(String taskId, MLTtsWarn warn) {
}

@Override
public void onRangeStart(String taskId, int start, int end) {
}

@Override
public void onEvent(String taskId, int eventName, Bundle bundle) {
if (eventName == MLTtsConstants.EVENT_PLAY_STOP) {
if (!bundle.getBoolean(MLTtsConstants.EVENT_PLAY_STOP_INTERRUPTED)) {
Toast.makeText(ReadPhotoActivity.this.getApplicationContext(), R.string.read_finish, Toast.LENGTH_SHORT).show();
}
}
}
};
mlTtsEngine.setTtsCallback(callback);
}

5.Set the buttons for reading photos, taking photos, and reading aloud.

this.relativeLayoutLoadPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ReadPhotoActivity.this.selectLocalImage(ReadPhotoActivity.this.REQUEST_CHOOSE_ORIGINPIC);
}
});
this.relativeLayoutTakePhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ReadPhotoActivity.this.takePhoto(ReadPhotoActivity.this.REQUEST_TAKE_PHOTO);
}
});

6.Start TextAnalyzer() during the callback of photographing and reading photos.

private void startTextAnalyzer() {
if (this.isChosen(this.originBitmap)) {
MLFrame mlFrame = new MLFrame.Creator().setBitmap(this.originBitmap).create();
Task<MLText> task = this.textAnalyzer.asyncAnalyseFrame(mlFrame);
task.addOnSuccessListener(new OnSuccessListener<MLText>() {
@Override
public void onSuccess(MLText mlText) {
// Transacting logic for segment success.
if (mlText != null) {
ReadPhotoActivity.this.remoteDetectSuccess(mlText);
} else {
ReadPhotoActivity.this.displayFailure();
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// Transacting logic for segment failure.
ReadPhotoActivity.this.displayFailure();
return;
}
});
} else {
Toast.makeText(this.getApplicationContext(), R.string.please_select_picture, Toast.LENGTH_SHORT).show();
return;
}
}

7.After the recognition is successful, click the play button to start the playback.

this.relativeLayoutRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ReadPhotoActivity.this.sourceText == null) {
Toast.makeText(ReadPhotoActivity.this.getApplicationContext(), R.string.please_select_picture, Toast.LENGTH_SHORT).show();
} else {
ReadPhotoActivity.this.mlTtsEngine.speak(sourceText, MLTtsEngine.QUEUE_APPEND);
Toast.makeText(ReadPhotoActivity.this.getApplicationContext(), R.string.read_start, Toast.LENGTH_SHORT).show();
}
}
});

Demo

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/034/238/374/5190001000034238374.20200624063613.61104657732468160159798668915977:50510630055936:2800:0274E412DE6EB5A08EAD2FA50B7CDFE527E01FD3CC386E57FAF0004747B455F2.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/034/238/374/5190001000034238374.20200624063613.61104657732468160159798668915977:50510630055936:2800:0274E412DE6EB5A08EAD2FA50B7CDFE527E01FD3CC386E57FAF0004747B455F2.gif[/IMG]

Any questions about this process, you can visit HUAWEI Developer Forum.