3

A "cold" knowledge, it's the Chinese Valentine's Day!

At this time of each year, gift-giving guides are flying all over the sky, and selection difficulties are forced out, and people who are puzzled, who can fix love, are extremely entangled in gift-giving!
To me, the most important thing is to create an atmosphere for a romantic festival like the Valentine's Day! Today, I would like to introduce a small gift for programmers that is "full of atmosphere" for the Chinese -16119bfa705eb8, with the help of 16119bfa705ebb Huawei image service , to develop a super-loving Chinese , which supports the input of special keywords and triggers the special effects of "Chinese Valentine’s Day" ; At the same time, the screen can also follow the fingertip touch to produce dynamic effects...... The effect is quick to see ↓↓↓

Demo effect

Shows with objects are shown to the objects. Single friends can also be a member of the Qixi atmosphere group first. The method is available, and maybe you will use it next time.

Not much to say, open the whole!

Development steps

1. Keyword animation playback

The first step: material preparation

First find a suitable picture, here we choose a picture of Cowherd and Weaver Girl:

Then take out the parts with animation effects from the picture. We took out the four elements of Cloud, Cowherd, Weaver Girl and Red Heart.

Step 2: Preparation for integration

Follow the instructions below to complete developer registration, create an application, and sign configuration:
https://developer.huawei.com/consumer/cn/doc/development/Media-Guides/config-agc-0000001050199019?ha_source=hms1

Then configure the code warehouse and compilation dependencies as follows:

1) Configure in the project-level "build.gradle" file:

buildscript {
    repositories {
        google()
        jcenter()
        // 配置HMS Core SDK的Maven仓地址。
        maven {url 'https://developer.huawei.com/repo/'}
    }
    dependencies {
        ...
        // 增加agcp插件配置。
        classpath 'com.huawei.agconnect:agcp:1.4.2.300'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        // 配置HMS Core SDK的Maven仓地址。
        maven {url 'https://developer.huawei.com/repo/'}
    }
}

2) Configure compilation dependencies in the application-level "build.gradle" file (currently the latest version 1.0.3.301):

dependencies { 
implementation 'com.huawei.hms:image-render: 1.0.3.301' 
  implementation 'com.huawei.hms:image-render-fallback: 1.0.3.301'
}

3) Configure permissions

Configure the required permissions for the application in the "AndroidManifest.xml" file.

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Step 3: Function development

1) Interface design

The simplest interface is used here, the input boxes and buttons are configured in a FrameLayout:

We will debug and show animation in this FrameLayout.

2) Configure storage permission application

In the onCreate() method of MainActivity, check whether you have the permission to write storage. If it is missing, call the requestPermission method to apply for the WRITE_EXTERNAL_STORAGE permission:

int permissionCheck = ContextCompat.checkSelfPermission(ImageKitRenderDemoActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
initData();
initImageRender();
} else {
ActivityCompat.requestPermissions(ImageKitRenderDemoActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}

If you have permission, or after the permission application is successful, initialize the Image rendering module

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == PERMISSION_REQUEST_CODE) {
        if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // The permission is granted.
            initData();
            initImageRender();
        } else {
            // The permission is rejected.
            Log.w(TAG, "permission denied");
            Toast.makeText(ImageKitRenderDemoActivity.this, "Please grant the app the permission to read the SD card", Toast.LENGTH_SHORT).show();
        }
    }
}

3) Image rendering module initialization

Get the rendering instance, initialize, and get the rendering view. The directory of animation elements will be specified here:

ImageRender.getInstance(context, new ImageRender.RenderCallBack() {
        // 获取场景动效服务实例成功回调,返回场景动效服务实例
        @Override
        public void onSuccess(ImageRenderImpl imageRender) {
            imageRenderAPI = imageRender;
            if (imageRenderAPI != null) {
                int initResult = imageRenderAPI.doInit(sourcePath, Utils.getAuthJson());
                Log.i(TAG, "DoInit result == " + initResult);
                if (initResult == 0) {
                    // Obtain the rendered view.
                    RenderView renderView = imageRenderAPI.getRenderView();
                    if (renderView.getResultCode() == ResultCode.SUCCEED) {
                        View view = renderView.getView();
                        if (null != view) {
                            // Add the rendered view to the layout.
                            contentView.addView(view);
                            hashCode = String.valueOf(view.hashCode());
                        } else {
                            Log.w(TAG, "GetRenderView fail, view is null");
                        }
            }
        }
        // 获取场景动效服务实例失败回调,返回错误码
        @Override
        public void onFailure(int errorCode) {
        ...
        }
    });

4) Configure keywords to play animation

Remember the input boxes and buttons left earlier? We use the keyword "Love" for animation playback. It can be triggered only by imageRenderAPI.playAnimation():

wordInput = findViewById(R.id.textinput);
enterBtn = findViewById(R.id.enter);
enterBtn.setOnClickListener(v -> {
    String inputContent = wordInput.getText().toString();
    if (inputContent.contentEquals("Love")) {
        if (null != imageRenderAPI) {
            imageRenderAPI. playAnimation();;
            wordInput.setVisibility(View.GONE);
            enterBtn.setVisibility(View.GONE);
        }
    } else {
        Toast.makeText(this,"再想想?",Toast.LENGTH_SHORT).show();
    }
});

5) Configure animation

The frame is set up, now we come to the animation part. Image Kit provides 5 basic motion effects and 9 advanced motion effects, which can meet the requirements of most scenes.
Here we use transparency animation, displacement animation, zoom animation, and falling animation.

The animation configuration of Image Kit is completed in the manifest.xml file. Don't confuse it with the AndroidManifest.xml file.

First configure the virtual screen width and background image. After configuring the virtual screen width, the system will scale the animation according to different resolutions to keep the effect consistent.

<Root screenWidth="1080">
<Image src="background.png"/>

We hope that the Cowherd and Weaver Girl can gradually approach until they meet. At this time, add the two elements of Cowherd and Weaver Girl and configure the moving lines separately. At this time, the special effects of the displacement animation are used:

 <Image x="1000" y="1450" src="man.png">
       <PositionAnimation repeat="1">
           <Position x="0" y="0" time="0"/>
           <Position x="-450" y="-100" time="4000"/>
       </PositionAnimation>
    </Image>
    <Image x="-600" y="800" src="woman.png">
        <PositionAnimation repeat="1">
            <Position x="0" y="0" time="0"/>
            <Position x="700" y="300" time="4000"/>
        </PositionAnimation>
    </Image>

In this way, the Cowherd and the Girl Weaver will approach the center from both sides of the screen until they meet.

After the meeting, a beating red heart will appear in the center. Transparency animation and zoom animation superimposition effects are used here:

 <Image x="520" y="1350"  src="heart.png" visibility="#show1">
        <AlphaAnimation delay="4000" repeat="1">
            <Alpha a="255" time="0"/>
            <Alpha a="0" time="3000"/>
        </AlphaAnimation>
        <SizeAnimation delay="4000" repeat="1">
            <Size w="127" h="95" time="0"/>
            <Size w="508" h="380" time="3000"/>
        </SizeAnimation>
    </Image>

Up to now, the key elements are already there, but it still looks a bit dry. Find something to embellish.
The clouds in the sky can also move, making it more agile when moving in a small area:

 <Image x="150" y="200" src="cloud.png">
        <PositionAnimation repeat="0">
            <Position x="0" y="0" time="0"/>
            <Position x="-50" y="0" time="3000"/>
            <Position x="0" y="0" time="6000"/>
        </PositionAnimation>
    </Image>

I want to be more romantic and sprinkle some petals. Here is the falling motion effect:

 <DropPhysicalView gravityX="3" gravityY="10" airDensity="1000" delay="8800" visibility="#show2">
        <ItemGroup x="0" y="0" width="#screen_width" height="#screen_height">
            <Alpha x="0" y="#screen_height-1000" width="#screen_width" height="#screen_height" value="20"/>
            <Item count="20" src="follow.png">
                <Velocity isRandom="true" velocityX="0" velocityY="5"/>
                <Position isRandom="true"/>
                <AngleVelocity isRandom="true" angleVelocity="5"/>
                <Weight isRandom="true" value="0.5"/>
            </Item>
        </ItemGroup>
    </DropPhysicalView>

6) You're done here. Finally, you can keep the animation

// 开始录制
int resultCode = imageRenderAPI.startRecord(json, new IStreamCallBack () {
    // 在录制成功回调中,将视频或GIF字节数组保存成mp4或GIF文件
    @Override
    void onRecordSuccess(HashMap<String, Object> map) {
        ...
        String recordType = (String) hashMap.get("recordType");
        byte[] videoBytes = (byte[]) hashMap.get("videoBytes");
        byte[] gifBytes = (byte[]) hashMap.get("gifBytes");
        try {
            if (recordType.equals("1")) {
                if (videoBytes != null) {
                    // 保存mp4文件
                    saveFile(videoBytes, mp4Path);
                }
            } else if (recordType.equals("2")) {
                ...
            } else if (recordType.equals("3")) {
                ...
            }
        } catch (IOException e) {
            ...
        }
        ...
    }

    // 录制失败回调
    @Override
    void onRecordFailure(HashMap<String, Object> map) {
        ...
    }

    // 录制进度回调,progress取值范围为0-100
    @Override
    void onProgress(int progress) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                textProgress.setText("当前录制进度:" + progress + "%");
            }
        });
    }
});

The above will get the final effect~

In addition to dynamic effects, Image Kit also provides a filter function, which can add romantic colors to pictures, the function of stickers and flowers, and it can also add love elements to users' pictures.

Learn more>>

Visit Huawei Image Service official website

Visit Huawei Developer Alliance official website

Obtain development guide document

Huawei Mobile Services open source warehouse address: GitHub , Gitee

Follow us and learn about the latest technical information of HMS Core


HarmonyOS_SDK
596 声望11.7k 粉丝

HarmonyOS SDK通过将HarmonyOS系统级能力对外开放,支撑开发者高效打造更纯净、更智能、更精致、更易用的鸿蒙原生应用,和开发者共同成长。