「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」
前言
之前, 通过使用 OpenCV 提供的四种非真实渲染的使用场景:边缘保留滤波
、细节增强
、素描铅笔画
、风格化
,我们模拟不同的绘制风格,让图片更具特点。但是 4 种场景显然无法满足我们对美好图片的向往。华为图像服务(HUAWEI Image Kit)为开发者提供图像智能编辑与设计、场景动效制作能力,高效地实现图片内容再生产,可以辅助设计师设计图片。今天,我们看看如何使用华为图片滤镜服务来润色图片。
介绍
滤镜服务提供小苍兰、蒹葭等 24 种独具特色的颜色滤镜,可以帮助开发者完成图片后期处理,实现图片高质量内容生产。
支持设备
设备类型 | OS版本 | HSM Core(APK)版本 |
---|---|---|
华为手机 | EMUI 8.0及以上 | 4.0.2及以上;若未安装,或安装了其他版本的APK,功能可以正常使用,但不支持版本自动升级。 |
非华为手机 | Android 8.0及以上 |
使用限制
滤镜服务的待解析图片不大于15M,图片分辨率不超过8000*8000,宽高比在1:3和3:1之间。
集成
开发环境
-
Android Studio 3.X 及以上
-
JDK 1.8 及以上
-
应用应满足以下条件:
- minSdkVersion 26
- targetSdkVersion 29
- compileSdkVersion 29
- Gradle 4.6及以上
如果同时使用多个HMS Core的服务,则需要使用各个Kit对应的最大值。
-
测试应用的设备:EMUI 8.0及以上的华为手机或Android 8.0 及以上的非华为手机
开发准备
配置AppGallery Connect
针对非上架华为应用市场的应用,只需要创建项目并创建应用即可。
- 注册成为开发者
- 创建项目和创建应用
- 生成签名证书指纹(若非华为应用市场上架应用,可忽略此步骤)
- 配置签名证书指纹(若非华为应用市场上架应用,可忽略此步骤)
集成HMS Core SDK
针对Android Studio开发环境,华为提供了Maven仓集成方式的HMS Core SDK包。在开始开发前,您需要将HMS Core SDK集成到您的Android Studio开发环境中。
- 添加当前应用的AppGallery Connect配置文件(若非华为应用市场上架应用,可忽略此步骤)
- 配置HMS Core SDK的Maven仓地址
buildscript {
repositories {
google()
jcenter()
// 配置HMS Core SDK的Maven仓地址。
maven {url 'https://developer.huawei.com/repo/'}
}
dependencies {
...
// 若非华为应用市场上架应用,无需配置agcp插件
}
}
allprojects {
repositories {
google()
jcenter()
// 配置HMS Core SDK的Maven仓地址。
maven {url 'https://developer.huawei.com/repo/'}
}
}
复制代码
- 添加编译依赖(若有版本更新,请及时更新版本)
implementation "com.huawei.hms:image-vision:1.0.3.301"
implementation "com.huawei.hms:image-vision-fallback:1.0.3.301"
复制代码
如果是在安装了 HMS Core(APK)的手机上使用 Image Kit 服务,则添加 SDK 服务的依赖。
如果需要在未安装 HMS Core(APK)的手机上使用 Image Kit 服务,则添加 fallback-SDK 的依赖。
- 配置minSdkVersion
android {
...
defaultConfig {
...
minSdkVersion 26
...
}
...
}
复制代码
- 同步工程
配置混淆脚本
- proguard-rules.pro
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
复制代码
- AndResGuard
"R.string.hms*",
"R.string.connect_server_fail_prompt_toast",
"R.string.getting_message_fail_prompt_toast",
"R.string.no_available_network_prompt_toast",
"R.string.third_app_*",
"R.string.upsdk_*",
"R.layout.hms*",
"R.layout.upsdk_*",
"R.drawable.upsdk*",
"R.color.upsdk*",
"R.dimen.upsdk*",
"R.style.upsdk*"
复制代码
添加权限
<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"/>
复制代码
应用开发
获取滤镜服务实例
// 获取ImageVisionImpl对象
imageVisionFilterAPI = ImageVision.getInstance(requireActivity())
复制代码
滤镜服务初始化
调用 setVisionCallBack 时需要实现 ImageVision.VisionCallBack 接口,重写其中的 onSuccess(int successCode) 和 onFailure(int errorCode) 方法。
- 框架初始化成功后会回调onSuccess方法,在onSuccess方法中,需要再初始化滤镜服务。调用滤镜初始化接口时,只有通过校验,第三方应用才能使用滤镜服务,initCode必须为0,滤镜服务初始化成功。
- 框架初始化失败时会回调onFailure方法,传回失败错误码。
imageVisionFilterAPI?.setVisionCallBack(object : VisionCallBack {
override fun onSuccess(successCode: Int) {
val initCode =
imageVisionFilterAPI?.init(requireActivity(), LocalAuthJson)
isInit = initCode == 0
Toast.makeText(
requireContext(),
if (initCode == 0) "ColorFilter Init Successfully" else "ColorFilter Init Failed\n, initCode: $initCode",
Toast.LENGTH_SHORT
).show()
}
override fun onFailure(errorCode: Int) {
Toast.makeText(
requireContext(),
"setVisionCallBack Failed",
Toast.LENGTH_SHORT
).show()
LogsUtil.e(
TAG,
"ImageVisionAPI fail, errorCode: $errorCode"
)
}
})
复制代码
参数 LocalAuthJson 是一个 JSONObject,包含
参数列表 | 类型 | M/O (必选/可选) |
---|---|---|
projectId | String | M |
appId | String | M |
authApiKey | String | M |
clientSecret | String | M |
clientId | String | M |
token | String | O(滤镜服务不需要) |
添加滤镜
构建请求参数,调用 getColorFilter 接口,输入待处理图片的 Bitmap ,并选择需要的滤镜效果。滤镜服务根据传入的参数对原始图片进行处理后,返回处理后图片的 Bitmap 。
private fun doFilter() {
if (!this::originBitmap.isInitialized) {
Toast.makeText(requireContext(), "Please Pick Image", Toast.LENGTH_SHORT).show()
return
}
lifecycleScope.launch(Dispatchers.IO) {
val jsonObject = JSONObject()
val taskJson = JSONObject()
try {
// 滤镜强度,取值范围[0,1.0],默认为1.0。
taskJson.put("intensity", "1")
// 颜色映射的图片索引,索引范围[0,24](0为原图)
taskJson.put("filterType", LocalFilters[filterIndex].code)
// 压缩率,取值范围(0,1.0],默认为1.0。
taskJson.put("compressRate", "1")
// 业务提供的请求ID(可选)
jsonObject.put("requestId", "1")
jsonObject.put("taskJson", taskJson)
// 鉴权参数,与初始化过程中使用的相同
jsonObject.put("authJson", LocalAuthJson)
// 获取visionResult返回值
val visionResult = imageVisionFilterAPI?.getColorFilter(
jsonObject,
originBitmap
)
withContext(Dispatchers.Main) {
if (visionResult?.resultCode == 0) {
val image = visionResult.image
mBinding.picture.setImageBitmap(image)
} else {
Toast.makeText(
requireContext(),
"resultCode: ${visionResult?.resultCode}",
Toast.LENGTH_SHORT
).show()
}
}
LogsUtil.e(TAG, "visionResult: $visionResult")
} catch (e: JSONException) {
LogsUtil.e(TAG, "JSONException: " + e.message)
}
}
}
复制代码
filterType 映射表
停止服务
当不再需要滤镜效果时,调用该接口停止服务,stopCode为 0 时,停止服务成功。
val stopCode = imageVisionFilterAPI?.stop()
复制代码