Skip to content

omeshi1/RealCUGAN-ncnn-Android

Repository files navigation

RealCUGAN-ncnn-Android

项目简介

基于 nihui/realcugan-ncnn-vulkan 移植的 Real-CUGAN 超分辨率模型 Android 封装。使用 ncnn + Vulkan 实现,免 CUDA/PyTorch,适配移动端 CPU 与 Qualcomm GPU,支持后台运行与并发控制。

本项目使用了GPT进行辅助编码与设计。

特性

  • 跨平台 & Android 优化
    • ncnn + Vulkan 推理,支持 Qualcomm / Mali / Adreno GPU。
    • 自动检测设备,动态调整 tilesize,避免输出纯黑。
  • 参数校验
    • noisescalesyncgapgpuId 严格范围检查,非法值抛异常。
  • Service 模式
    • 内置前台 Service,通知栏显示进度/文件名,可禁用通知。
    • 提供 Binder API:process()configureConcurrency()dispose()
  • 内存管理
    • Native 层修复透明度 tile 裁剪问题。(参考了tumuyan的修复方法
    • 主动回收位图 (recycle()),避免 Graphics 占用过高。
    • dispose() / release() 立即归还 native & Vulkan 资源。

快速开始

  1. 添加 JitPack 仓库:
allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
  1. 添加依赖:
dependencies {
    implementation 'com.github.akari39:RealCUGAN-ncnn-Android:1.1'
}
  1. 创建模型:
val opts = RealCUGANOption(
    context = this,
    noise = -1,
    scale = 2,
    syncgap = 3,
    modelName = ModelName.SE,
    ttaMode = false,
    gpuId = 0
)
val engine = RealCUGAN.create(opts)
  1. 执行推理:
val outBmp = engine.process(inputBytes, { percent -> 
    // 进度回调 
} )
imageView.setImageBitmap(outBmp)
  1. 释放资源:
engine.release()

Service 模式使用

现已加入前台 Service 封装,可以在后台执行任务并显示进度通知。如果懒得配置并想安全使用可以直接用封装好的 Service。

  1. 启动 Service:
val intent = Intent(this, RealCUGANService::class.java)
    .putExtra(RealCUGANService.EXTRA_ENABLE_NOTIFICATION, true)
    .putExtra(RealCUGANService.EXTRA_MAX_CONCURRENT, 2)
    .putExtra(RealCUGANService.EXTRA_QUEUE_ENABLED, true)
ContextCompat.startForegroundService(this, intent)
  1. 绑定并提交任务:
bindService(intent, conn, Context.BIND_AUTO_CREATE)

binder.process(bytes, "test.png", listener) { result ->
    result.onSuccess { bmp -> imageView.setImageBitmap(bmp) }
    result.onFailure { e -> Log.e("RealCUGAN", "failed", e) }
}
  1. 回收 Service:
binder.dispose()
unbindService(conn)
stopService(intent)

⚠️ 注意事项

  • 请尽量只创建一个实例,避免显存竞争。
  • 压测/批量任务结束后务必调用 dispose()release()