HMS Kullanarak Resimlerinizi Düzenleyin (ML Kit, Cloud Storage, Auth Service) Android - Kotlin

Sezer Özaltun
Huawei Developers - Türkiye
6 min readMay 17, 2023
Projede Kullanılan Huawei Servisleri

Giriş

Herkese merhaba, yeni bir içerikle karşınızdayım. Bu makalede Huawei mobil servislerinden ML Kit, Cloud Storage ve Auth Service kullanarak fotoğraflarınızın arka planını nasıl kaldıracağınızı anlatacağım.

ML Kit ile fotoğrafın arka planını kaldıracağız

Cloud Storage kullanarak düzenlediğimiz fotoğrafları güvenli bir şekilde cloud’a yükleyeceğiz ve her yerden erişebilme imkanımız olacak. Cloud Storage işlemeri olan upload, download, delete ve listeleme özelliklerini kullacağız.

Auth Service ise bize Cloud Storage kullanımında authentication için lazım olacak.

Servislerin Entegre Edilmesi

Kodlama kısmına başlamadan önce uygulamanıza HMS Core entegre etmeniz gerekiyor. Bunun için buradaki bağlantıya tıklayabilirsiniz.

Servisleri projemize entegre etmek için yapmamız gereken birkaç adım bulunmakta.

1. AppGallery Connect’e giriş yapın ve My Projects’e tıklayın.

AppGallery Connect My Projects

2. Servisleri kullanmak istediğiniz projeyi seçin.

Proje seçme

3. ML Kit ve Auth Service kullanabilmek için Manage APIs sekmesine tıklayın, ML Kiti ve Auth Service aktifleştirin.

ML Kit Aktifleştirme
Auth Service Aktifleştirme

4. Cloud Storage Kullanmak için ise aşağıdaki adımları gerçekleştirmemiz gerekiyor.

Cloud Storage Aktifleştirme
İstediğiniz instance belirleyebilirsiniz. Default location seçmelisiniz.
Finish diyerek işlem tamamlanmış olacaktır.

5. Android Studio içerisinde AndroidManifest.xml dosyasına gerekle izinleri ekleyelim.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="false"
android:requestLegacyExternalStorage="true"
.
.
. <meta-data
android:name="com.huawei.hms.ml.DEPENDENCY"
android:value="imgseg" />
</application>

6. Gerekli bağımlılıkları build.gradle içerisine ekleyelim.

 //Huawei Auth
implementation 'com.huawei.agconnect:agconnect-auth:1.6.5.300'
//Ml Kit
implementation 'com.huawei.hms:ml-computer-vision-segmentation:3.7.0.302'
// Import the multiclass segmentation model package.
implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-multiclass-model:3.7.0.302'
// Import the human body segmentation model package.
implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:3.7.0.302'
// Import the hair segmentation model package.
implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-hair-model:3.7.0.302'
//Cloud Storage
implementation "com.huawei.agconnect:agconnect-storage:1.5.0.100"

Uygulama

Şu ana kadar gerekli olan servisleri AppGallery Connect üzerinden aktifleştirdik ve gerekli bağımlılıkları projemize ekledik. Eğer herhangi bir hata ile karşılaştıysanız veya daha detaylı incelemek isterseniz makalenin sonundaki referanslar bölümünden ilgili kaynakları inceleyebilirsiniz.

ML Kit Uygulanması

   var setting = MLImageSegmentationSetting.Factory()
.setExact(true)
.setAnalyzerType(MLImageSegmentationSetting.BODY_SEG)
.setScene(MLImageSegmentationScene.FOREGROUND_ONLY)
.create()
analyzer = MLAnalyzerFactory.getInstance().getImageSegmentationAnalyzer(setting)
val drawable: BitmapDrawable = binding.imageView.drawable as BitmapDrawable
bitmap = drawable.bitmap
val mlFrame = MLFrame.Creator().setBitmap(bitmap).create()
val task: Task<MLImageSegmentation> = analyzer.asyncAnalyseFrame(mlFrame)
task.addOnSuccessListener {
removeBackGround(it)
}.addOnFailureListener {
Log.e(TAG1, "analyse -> asyncAnalyseFrame: ", it)
}

Yukarıdaki kod satırları ile yeni bir segmentation oluşturuyoruz. Burada insan analizi yapacağımız ve sadece ön planın kalmasını istediğimiz içi analyzer tipini BOD_SEG ve setScene’i ise FOREGROUND_ONLY olarak ayarlıyoruz. Daha sonra bitmap ile fotoğrafımızı seçiyoruz ve task success olduğu zaman removeBackGround metodunu çalıştırıyoruz.

private fun removeBackground(mlImageSegmentation: MLImageSegmentation?) {
if (mlImageSegmentation != null) {
if (bitmap == null) {
Log.e(TAG1, "bitmap is null")
return
}
val bitmapFore: Bitmap = mlImageSegmentation.getForeground()
if (bitmapFore != null) {
binding.imageView.setImageBitmap(bitmapFore)
} else {
Log.e(TAG1, "bitmap is null")
}
}
}

removeBackGround metodunun içinde bitmap ile gönderdiğimiz resmin arka planını MLImageSegmentation sınıfı ile siliyoruz.

Auth Service Uygulanması

Auth Service kullanmamızın amacı, Cloud Storage’ın bunu kullanırken bir authentication istemesidir.

     if (AGConnectAuth.getInstance().currentUser != null) {
DriverManager.println("already sign a user")
Log.i(TAG2, "already sign a user")
return
} else {
AGConnectAuth.getInstance().signInAnonymously()
.addOnSuccessListener {
DriverManager.println("AGConnect OnSuccess")
Log.i(TAG2, "AGConnect OnSuccess")
}
.addOnFailureListener { e ->
DriverManager.println("AGConnect OnFail: " + e.message)
Log.i(TAG2, "AGConnect OnFail ${e.message}")
}
}

Yukarıdaki kod satırı ile anonymously (anonim) olarak giriş yapıyoruz ve Cloud Storage kullanabiliyoruz. İsterseniz gerçek kullanıcı girişi de yapabilirsiniz.

Cloud Storage Uygulanması

Öncelikle aşağıdaki kod ile yazma ve okuma izinlerini almamız gerekiyor.

1. private val permissions = arrayOf<String>(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
2. ActivityCompat.requestPermissions(this, permissions, 1)

Sonrasında Cloud Storage kullanabilmek için storage management ile instance almamız gerekiyor. Bu instance bizim Cloud ile bağlantımızı sağlayacaktır.

private var mAGCStorageManagement: AGCStorageManagement? = null
val storageManagement = AGCStorageManagement.getInstance()
private fun initAGCStorageManagement() {
mAGCStorageManagement = AGCStorageManagement.getInstance()
Log.i(TAG2, "Init AGC Storage Management success! ")
}

Cloud Storage Upload

Aşağıdaki kod satırı ile fotoğrafımızı Cloud tarafına upload edebi liriz. Buradaki path cloud tarafındaki oluşturulacak dosyanın adıdır.

val progressDialog = ProgressDialog(this)
progressDialog.setMessage("Uploading File....")
progressDialog.setCancelable(false)
progressDialog.show()
val systemCurrentTime: Long = System.currentTimeMillis()
val path = "/images/${systemCurrentTime}.png"
val agcSdkDirPath = agcSdkDirPath
val file = File(agcSdkDirPath)
if (!file.exists()) {
Log.i(TAG2, "file is not exist!")
return
} else {
Log.i(TAG2, "file is exist")
val storageReference =
mAGCStorageManagement!!.getStorageReference(path)
val uploadTask = storageReference.putFile(file)

uploadTask.addOnSuccessListener {
Log.i(TAG2, "upload success!")
progressDialog.dismiss()
}
.addOnFailureListener { e: Exception ->
progressDialog.dismiss()
Log.i(
TAG2,
"Upload Failed $e"
)
}
}
private val agcSdkDirPath: String
get() {
DriverManager.println("path=$path")
val dir = File(path)
if (!dir.exists()) {
dir.mkdirs()
}
return path!!
}

Cloud Storage Listeleme

Aşağıdaki kod satırları ile images/ klasörüne upload yaptığımız dosyaları görüntüleyebiliriz ve liste üzerinde gösterebiliriz.

val path = "images/"
val storageReference = mAGCStorageManagement?.getStorageReference(path)
var listResultTask: Task<ListResult>? = null
listResultTask = storageReference?.list(100)
listResultTask?.addOnSuccessListener {
fileList = ArrayList(it.fileList)
mAdapter = DownloadListAdapter(
this@DownloadListActivity,
fileList = fileList,
mAGCStorageManagement,
this@DownloadListActivity
)
binding.recyclerView.adapter = mAdapter
mAdapter.notifyDataSetChanged()

Log.i("MYSTORAGE", "SUCCEDD: ${fileList.size}")
}?.addOnFailureListener {
Log.e("MYSTORAGE", "FAIL: ${it.printStackTrace()}")
}
}

Cloud Storage İndirme

Cloud üzerinden herhangi bir dosyamızı indirmek istediğimizde o dosyanın yolunu ve adını doğru tanımlamamız gerekiyor bunun için File metoduna agcSdkDirPath ve fileName parametrelerini tanımladım ve storageReference.getFile(file) ile dosya indirme isteği gönderiyorum.

     val progressDialog = ProgressDialog(context)
progressDialog.setMessage("Downloading File....")
progressDialog.setCancelable(false)
progressDialog.show()
val fileName = fileName
val path = path
val agcSdkDirPath = agcSdkDirPath2
val file = File(agcSdkDirPath, fileName)
val storageReference = mAGCStorageManagement!!.getStorageReference(path)
val downloadTask = storageReference.getFile(file)
downloadTask.addOnSuccessListener {
Toast.makeText(context, "Download Succeed", Toast.LENGTH_SHORT).show()
progressDialog.dismiss()
}.addOnFailureListener { e: Exception ->
Toast.makeText(context, "Download Error", Toast.LENGTH_SHORT).show()
progressDialog.dismiss()
Log.i("MYSTORAGE", "DOWNLOAD ERROR: $e")
}
private val agcSdkDirPath2: String
get() {
val path =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absoluteFile.toString()
DriverManager.println("path=$path")
val dir = File(path)
if (!dir.exists()) {
dir.mkdirs()
}
return path
}

Cloud Storage Silme

Dosya indirmede olduğu gibi path doğru verilmeli ve storageReference.delete() metodu çağırılmalı.

val path = path
DriverManager.println("path=%s$path")
val storageReference = mAGCStorageManagement!!.getStorageReference(path)
val deleteTask = storageReference.delete()
deleteTask.addOnSuccessListener {
Toast.makeText(context, "Delete Succeed", Toast.LENGTH_SHORT).show()
activity.getAllList()
notifyDataSetChanged()

}
.addOnFailureListener { e: Exception ->
Toast.makeText(context, "Delete Error:", Toast.LENGTH_SHORT).show()
Log.i("MYSTORAGE", "DELETE ERROR: $e")
}
Ekran Görüntüleri

Sonuç

Bu makalede, ML Kiti kullanarak fotoğrafların arka planını sildik. Cloud Storage kullanarak arka planını sildiğimiz fotoğraları Cloud tarafına yükledik, fotoğraflarımızı listeleme ve silme işlemlerini gerçekleştirdik. Umarım sizler için faydalı bir makale olmuştur.

--

--