The emoji package doutu, as a new joy in life, has been the majority of Internet users every day through the chat and interaction. What belly laugh, full of grooves, completely speechless… These thousands of words can not aptly describe the emotional details, can always be a seemingly ordinary emoji package perfect description, it can be said that a picture worth a thousand words, four two dial a thousand jin!

Nowadays, in the heated stage of emoji bucket map, people’s demand for customized emojis is increasing. Everyone is the porter of emojis, and everyone is also the creator of potential heat map! It is necessary to give individuals the ability to create personalized memes. Using the image segmentation function of machine learning, we can easily split complex image backgrounds, making emoji making simple and efficient. Let’s take a look at how to turn an image into a emoticons.

The development of preparation

For details on how to configure the Maven repository and SDK, see the Application Development guide on the developer website

Developer.huawei.com/consumer/cn…

Configure the integrated SDK package

Image segmentation provides two SDK integration methods. One is to pre-integrate the segmentation algorithm package into the application, and the other is to download the required algorithm package into the application after the application is installed and run, which can be selected according to the application’s usage scenario and required effects. In this article, we use the integration solution of Full SDK. Add the SDK dependencies for image segmentation in the build.gradle file in dependencies

Implementation 'com. Huawei. HMS: ml - computer vision - segmentation: 2.2.0.300' implementation 'com. Huawei. HMS: ml - computer vision - image segmentation - body - model: 2.2.0.300'Copy the code

Configuration AndroidManifest. XML

Open the Androidmanifest.xml file in the main folder. You can configure the permission to read and write the mobile phone storage according to the scenario and use requirements

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Copy the code

Add the following statement to it. When the application is installed, it will automatically update the latest machine learning model to the device

<meta-data
    android:name="com.huawei.hms.ml.DEPENDENCY"
    android:value= "imagesuperresolution"/>
Copy the code

Development steps

Configure the storage permission application

In addition to declaring storage permissions on the phone in the Manifest, you also need to dynamically apply for them in the Activity. In the onCreate() method of the MainActivity, call the requestPermission method to apply for WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE permissions

Protected void onCreate(Bundle savedInstanceState) {... requestPermission(Manifest.permission.READ_EXTERNAL_STORAGE); requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE); ... }Copy the code

The requestPermission method is implemented as follows: first, the permission is determined. If the permission has not been obtained, the request is made, and if it has been obtained, the return is returned

private void requestPermission(String permisssions) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return;
    }
		    if (ContextCompat.checkSelfPermission(this, permisssions)
            != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{permisssions}, REQUEST_CODE);
    } else {
        return;
    }
}
Copy the code

Read the pictures in the album

We first select the image from the album that we want to make memes with, create a button chooseImg in the XML file, click it and call the selectLocalImage method

this.relativeLayoutLoadPhoto = this.findViewById(R.id.chooseImg); this.relativeLayoutLoadPhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MainActivity.this.selectLocalImage(StillCutPhotoActivity.this.REQUEST_CHOOSE_ORIGINPIC); }});Copy the code

The implementation of the selectLocalImage method is as follows

private void selectLocalImage(int requestCode) {
    Intent intent = new Intent(Intent.ACTION_PICK, null);
    intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
    this.startActivityForResult(intent, requestCode);
}
Copy the code

Image segmentation to make emoticons

Create another button cut, click it and call createImageTransactor to create the image segmentation analyzer

this.relativeLayoutCut = this.findViewById(R.id.cut); this.relativeLayoutCut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (MainActivity.this.imageUri == null) { Toast.makeText(MainActivity.this.getApplicationContext(), R.string.please_select_picture, Toast.LENGTH_SHORT).show(); } else { MainActivity.this.createImageTransactor(); Toast.makeText(MainActivity.this.getApplicationContext(), R.string.cut_success, Toast.LENGTH_SHORT).show(); }}});Copy the code

In the createImageTransactor method, we first create an image segmentation analyzer and configure it to portrait segmentation mode

private MLImageSegmentationAnalyzer analyzer;

MLImageSegmentationSetting setting = new MLImageSegmentationSetting.Factory().setAnalyzerType(MLImageSegmentationSetting.BODY_SEG).create();
this.analyzer = MLAnalyzerFactory.getInstance().getImageSegmentationAnalyzer(setting);
Copy the code

Select a file from your album and open it as a Bitmap using imageUri

Pair<Integer, Integer> targetedSize = this.getTargetSize();
int targetWidth = targetedSize.first;
int targetHeight = targetedSize.second;
this.originBitmap = BitmapUtils.loadFromPath(StillCutPhotoActivity.this, this.imageUri, targetWidth, targetHeight);
Copy the code

Then create MLFrame and call asyncAnalyseFrame for asynchronous image segmentation

MLFrame mlFrame = new MLFrame.Creator().setBitmap(this.originBitmap).create();
Task<MLImageSegmentation> task = this.analyzer.asyncAnalyseFrame(mlFrame);
Copy the code

After the image segmentation is completed, the returned results are processed and the image with the background removed is saved to the Procesdisliked age

task.addOnSuccessListener(new OnSuccessListener<MLImageSegmentation>() {
    @Override
    public void onSuccess(MLImageSegmentation mlImageSegmentationResults) {
        // Transacting logic for segment success.
        if (mlImageSegmentationResults != null) {
            StillCutPhotoActivity.this.foreground = mlImageSegmentationResults.getForeground();
            StillCutPhotoActivity.this.preview.setImageBitmap(StillCutPhotoActivity.this.foreground);
            StillCutPhotoActivity.this.processedImage = ((BitmapDrawable) ((ImageView) StillCutPhotoActivity.this.preview).getDrawable()).getBitmap();
        } else {
            StillCutPhotoActivity.this.displayFailure();
        }
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(Exception e) {
        // Transacting logic for segment failure.
        StillCutPhotoActivity.this.displayFailure();
        return;
    }
});
Copy the code

Save memes

Finally, the processed image is converted into PNG format and stored in the system album

public void saveToAlbum(Bitmap bitmap){
    File file = null;
    String fileName = System.currentTimeMillis() +".png";
    File root = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), this.context.getPackageName());
    File dir = new File(root, "image");
    if(dir.mkdirs() || dir.isDirectory()){
        file = new File(dir, fileName);
    }
    FileOutputStream os = null;
    try {
        os = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
        os.flush();

    } catch (FileNotFoundException e) {
        Log.e(TAG, e.getMessage());
    } catch (IOException e) {
        Log.e(TAG, e.getMessage());
    }finally {
        try {
            if(os != null) {
                os.close();
            }
        }catch (IOException e){
            Log.e(TAG, e.getMessage());
        }
    }
    if(file == null){
        return;
    }
    if(imageUtilCallBack != null) {
        try {
            imageUtilCallBack.callSavePath(file.getCanonicalPath());
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
        }
    }
    // Gallery refresh.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        String path = null;
        try {
            path = file.getCanonicalPath();
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
						}
        MediaScannerConnection.scanFile(this.context, new String[]{path}, null,
                new MediaScannerConnection.OnScanCompletedListener() {
                    @Override
                    public void onScanCompleted(String path, Uri uri) {
                        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                        mediaScanIntent.setData(uri);
                        ImageUtils.this.context.sendBroadcast(mediaScanIntent);
                    }
                });
    } else {
        String relationDir = file.getParent();
        File file1 = new File(relationDir);
        this.context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(file1.getAbsoluteFile())));
    }
}
Copy the code

Effect of the sample

After compiling and running, you can select the photo you want to make emoji package from the album, click Cut, ML Kit will complete the following steps of portrait recognition and image segmentation, remove the messy background, return to the image of the portrait, and then click Save to Save it as the emoji package without background.

After saving, you can add your emojis to your social apps. Check them out!

For more information, visit huawei Machine Learning Image Segmentation service website

Obtain the Huawei machine learning service development guide document

Huawei HMS Core official forum

Huawei machine learning open source warehouse address: GitHub, Gitee

To solve integration problems, go to Stack Overflow

Click here to learn about the latest HMS Core technology