丹青识画系统Android端轻量化SDK集成教程

张开发
2026/4/5 12:27:35 15 分钟阅读

分享文章

丹青识画系统Android端轻量化SDK集成教程
丹青识画系统Android端轻量化SDK集成教程你是不是也想过要是手机摄像头对准一幅画、一株植物或者一个建筑就能立刻知道它的名字和背后的故事那该多酷这种“所见即所得”的智能识别现在通过丹青识画系统的轻量化SDK就能轻松集成到你的Android应用里。这个SDK专为移动端设计体积小巧识别速度快而且功能强大。无论是想做一个艺术品鉴赏App还是开发一个植物识别工具甚至是做一个旅游景点的AR导览它都能成为你应用的“智慧之眼”。今天我就手把手带你从零开始把这个“智慧之眼”装进你的Android应用里。1. 开始前的准备工作在动手敲代码之前咱们得先把“工具箱”准备好。这个过程很简单就像给手机装一个新App前先看看手机系统版本够不够一样。1.1 环境要求首先确保你的开发环境满足以下要求Android Studio建议使用最新稳定版比如海豚Dolphin或更高版本。Android SDK你的项目需要支持Android 5.0 (API level 21)或更高版本。这是SDK运行的最低要求。网络权限因为需要调用云端识别服务所以你的应用必须拥有访问互联网的权限。1.2 获取移动端API KeySDK需要一把“钥匙”才能访问丹青识画的服务这把钥匙就是API Key。访问丹青识画系统的官方网站注册并登录开发者账号。进入控制台找到“移动端SDK”或类似的服务管理页面。创建一个新的应用系统会为你生成一个专属的移动端API Key。请务必妥善保管这个Key我们稍后会用到它。2. 在项目中集成SDK环境准备好了钥匙也拿到了现在就把SDK引入到我们的Android Studio项目中。2.1 添加仓库与依赖打开你的项目根目录下的build.gradle文件注意是Project级别的不是Module级别的在allprojects-repositories块中添加Maven仓库地址。allprojects { repositories { google() mavenCentral() // 添加丹青识画的Maven仓库 maven { url https://your-maven-repo-url } // 请替换为官方提供的实际仓库地址 } }然后打开你的App Module通常是app目录下的build.gradle文件在dependencies块中添加SDK依赖。dependencies { implementation com.danqing:vision-sdk-android:1.0.0 // 请使用最新的版本号 // 其他依赖... }添加完成后点击Android Studio右上角的“Sync Now”按钮同步一下项目Gradle会自动下载这个SDK库。2.2 配置权限与API KeySDK需要一些权限来工作主要是访问网络和摄像头/相册。打开app/src/main/AndroidManifest.xml文件在manifest标签内添加以下权限uses-permission android:nameandroid.permission.INTERNET / uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE / !-- 如果需要拍照功能 -- uses-permission android:nameandroid.permission.CAMERA / !-- 如果需要从相册选图 -- uses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE /接下来我们需要在合适的地方初始化SDK并传入API Key。一个比较推荐的位置是在你的Application类中。如果你没有自定义的Application类可以创建一个。// MyApp.kt import android.app.Application import com.danqing.vision.sdk.VisionSDK class MyApp : Application() { override fun onCreate() { super.onCreate() // 初始化SDK替换YOUR_MOBILE_API_KEY为你的真实Key VisionSDK.init(this, YOUR_MOBILE_API_KEY) } }别忘了在AndroidManifest.xml中注册这个Application类application android:name.MyApp ... ... /application3. 实现核心识别功能SDK集成好了现在来打造应用的核心——图片获取与识别。我们将实现两个最常见的功能拍照识别和从相册选择识别。3.1 构建图片选择界面我们先创建一个简单的界面放两个按钮分别对应“拍照”和“从相册选择”。这里用Activity和ViewBinding来快速实现。!-- activity_main.xml -- LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightmatch_parent android:orientationvertical android:gravitycenter android:padding20dp Button android:idid/btn_camera android:layout_widthwrap_content android:layout_heightwrap_content android:text拍照识别 android:layout_marginBottom20dp/ Button android:idid/btn_gallery android:layout_widthwrap_content android:layout_heightwrap_content android:text从相册选择/ ImageView android:idid/iv_preview android:layout_width300dp android:layout_height300dp android:layout_marginTop40dp android:scaleTypecenterCrop android:background#f0f0f0/ TextView android:idid/tv_result android:layout_widthmatch_parent android:layout_heightwrap_content android:layout_marginTop20dp android:gravitycenter android:textSize16sp/ /LinearLayout3.2 处理拍照与相册选择逻辑在MainActivity中我们需要处理按钮点击、权限申请以及启动相机或相册的Intent。// MainActivity.kt import android.content.Intent import android.content.pm.PackageManager import android.net.Uri import android.os.Bundle import android.provider.MediaStore import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import java.io.File class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding private lateinit var currentPhotoPath: String // 用于保存拍照的临时文件路径 companion object { private const val REQUEST_CAMERA 1 private const val REQUEST_GALLERY 2 private const val REQUEST_CAMERA_PERMISSION 101 } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.btnCamera.setOnClickListener { // 检查并申请相机权限 if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) ! PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.CAMERA), REQUEST_CAMERA_PERMISSION) } else { openCamera() } } binding.btnGallery.setOnClickListener { // 启动相册选择 val intent Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) startActivityForResult(intent, REQUEST_GALLERY) } } private fun openCamera() { val intent Intent(MediaStore.ACTION_IMAGE_CAPTURE) // 创建临时文件保存照片 val photoFile File.createTempFile(JPEG_${System.currentTimeMillis()}_, .jpg, externalCacheDir) currentPhotoPath photoFile.absolutePath val photoURI FileProvider.getUriForFile(this, ${packageName}.fileprovider, photoFile) intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI) startActivityForResult(intent, REQUEST_CAMERA) } override fun onRequestPermissionsResult(requestCode: Int, permissions: Arrayout String, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode REQUEST_CAMERA_PERMISSION grantResults.isNotEmpty() grantResults[0] PackageManager.PERMISSION_GRANTED) { openCamera() } else { // 权限被拒绝可以给用户一个提示 } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (resultCode ! RESULT_OK) return when (requestCode) { REQUEST_CAMERA - { // 拍照返回图片已保存在 currentPhotoPath val imageFile File(currentPhotoPath) val imageUri Uri.fromFile(imageFile) binding.ivPreview.setImageURI(imageUri) uploadAndRecognize(imageUri) // 调用识别函数 } REQUEST_GALLERY - { // 相册返回 data?.data?.let { uri - binding.ivPreview.setImageURI(uri) uploadAndRecognize(uri) // 调用识别函数 } } } } // 下一步在这里实现 uploadAndRecognize 函数 }3.3 上传图片并获取识别结果这是最核心的一步。我们需要将获取到的图片URI转换成SDK能处理的格式通常是文件或字节数组然后调用SDK的识别接口。// 在 MainActivity.kt 中继续添加 import com.danqing.vision.sdk.VisionSDK import com.danqing.vision.sdk.callback.RecognitionCallback import com.danqing.vision.sdk.model.RecognitionResult import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import java.io.InputStream private fun uploadAndRecognize(imageUri: Uri) { binding.tvResult.text 识别中... // 在后台线程执行网络请求避免阻塞UI GlobalScope.launch(Dispatchers.IO) { try { // 1. 将Uri转换为字节数组 (这里是一个简化示例实际需处理不同来源的Uri) contentResolver.openInputStream(imageUri)?.use { inputStream: InputStream - val imageBytes inputStream.readBytes() // 2. 调用SDK识别接口 VisionSDK.recognizeImage(imageBytes, object : RecognitionCallback { override fun onSuccess(result: RecognitionResult) { // 切换到主线程更新UI runOnUiThread { displayRecognitionResult(result) } } override fun onFailure(errorCode: Int, errorMsg: String) { runOnUiThread { binding.tvResult.text 识别失败: $errorMsg } } }) } } catch (e: Exception) { runOnUiThread { binding.tvResult.text 处理图片时出错: ${e.message} } } } } private fun displayRecognitionResult(result: RecognitionResult) { // 这里展示一个最简单的文本结果 val resultText StringBuilder() resultText.append(识别成功\n\n) resultText.append(名称: ${result.name}\n) resultText.append(置信度: ${String.format(%.1f, result.confidence * 100)}%\n) resultText.append(描述: ${result.description}\n) // 可能还有其他字段如分类、百科链接等 binding.tvResult.text resultText.toString() }4. 进阶实现AR叠加展示如果只是显示文字感觉还不够“炫酷”。我们可以更进一步把识别结果以AR增强现实的方式叠加在原来的图片或相机预览画面上。这里我们用一个简化版的思路在图片上方绘制一个信息框。4.1 创建自定义AR信息视图我们可以创建一个自定义的View用来在ImageView上层绘制识别结果。// RecognitionOverlayView.kt import android.content.Context import android.graphics.* import android.util.AttributeSet import android.view.View class RecognitionOverlayView JvmOverloads constructor( context: Context, attrs: AttributeSet? null, defStyleAttr: Int 0 ) : View(context, attrs, defStyleAttr) { private var resultName: String? null private var resultRect: RectF? null // 假设SDK返回了物体在图片中的位置矩形 private val paint Paint().apply { color Color.GREEN style Paint.Style.STROKE strokeWidth 5f textSize 40f isAntiAlias true } private val textBgPaint Paint().apply { color Color.argb(180, 0, 0, 0) // 半透明黑色背景 style Paint.Style.FILL } fun updateRecognitionInfo(name: String?, rect: RectF?) { this.resultName name this.resultRect rect invalidate() // 触发重绘 } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) resultRect?.let { rect - // 1. 绘制识别框 canvas.drawRect(rect, paint) // 2. 在框的上方绘制标签 resultName?.let { name - val text name val textWidth paint.measureText(text) val textHeight paint.descent() - paint.ascent() val textX rect.centerX() - textWidth / 2 val textY rect.top - 10 // 在框上方10像素处 // 绘制文字背景 val bgRect RectF(textX - 10, textY - textHeight, textX textWidth 10, textY) canvas.drawRoundRect(bgRect, 5f, 5f, textBgPaint) // 绘制文字 paint.color Color.WHITE paint.style Paint.Style.FILL canvas.drawText(text, textX, textY, paint) // 恢复画笔状态 paint.color Color.GREEN paint.style Paint.Style.STROKE } } } }4.2 在布局和代码中使用修改之前的activity_main.xml将ImageView包裹在一个FrameLayout中并加入我们的RecognitionOverlayView。FrameLayout android:layout_width300dp android:layout_height300dp android:layout_marginTop40dp ImageView android:idid/iv_preview android:layout_widthmatch_parent android:layout_heightmatch_parent android:scaleTypecenterCrop/ com.yourpackage.RecognitionOverlayView android:idid/overlay_view android:layout_widthmatch_parent android:layout_heightmatch_parent/ /FrameLayout然后在displayRecognitionResult函数中不仅更新文本也更新AR叠加层。这里假设RecognitionResult包含了物体位置信息boundingBox。private fun displayRecognitionResult(result: RecognitionResult) { // ... 之前的文本更新代码 ... // 更新AR叠加视图 result.boundingBox?.let { box - // 假设box是一个RectF对象 // 需要将识别结果的坐标通常是相对于原图的转换到当前ImageView显示的坐标 // 这里涉及坐标转换是一个简化示例 val drawableRect RectF(0f, 0f, binding.ivPreview.width.toFloat(), binding.ivPreview.height.toFloat()) val scaleFactor calculateScaleFactor(box, drawableRect) // 需要实现这个计算函数 val overlayRect transformRect(box, scaleFactor) // 需要实现这个转换函数 binding.overlayView.updateRecognitionInfo(result.name, overlayRect) } }5. 总结与后续优化建议整个集成过程走下来你会发现其实核心步骤就那几步加依赖、初始化、传图片、拿结果。最难的部分可能在于处理Android的权限、图片URI以及UI交互但这些也是移动开发的日常。实际用起来这个轻量化SDK在速度和准确度上给我的印象不错。对于想快速给应用加上“识图”能力的开发者来说是个挺省心的选择。当然初次集成可能会在图片预处理、网络错误处理或者AR坐标转换上遇到点小麻烦多调试几次就好。如果你想做得更完善我建议可以从这几个地方再下点功夫用户体验在识别时加个加载动画失败时给个友好的提示甚至允许用户手动调整识别框。性能与缓存可以考虑对识别结果做本地缓存用户再次识别同一物体时能立刻显示。对于高清大图可以先压缩再上传节省流量和时间。功能拓展结合SDK可能提供的更多接口比如识别多个物体、获取更详细的百科信息甚至结合手机传感器数据做出更沉浸的AR体验。希望这篇教程能帮你顺利起步。动手试试吧把你的创意变成现实让应用真正“看懂”世界。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

更多文章