HiAI Image - Superresolución con Picasso y Kotlin
Published: 2020-09-21 22:42:25

Las imágenes se comprimen en una proporción alta para su almacenamiento y transferencia para ahorrar espacio de almacenamiento y reducir el tráfico. Como resultado de hacer imágenes más pequeñas, brinda beneficios al usuario, como mejorar la experiencia de red en su aplicación, reducir el ancho de banda y el consumo de datos.

Para este artículo, usaremos la superresolución de imagen HiAI de Huawei para mejorar la calidad de una imagen que se descargó en baja resolución con Picasso.


Picasso es una potente biblioteca de descarga y almacenamiento en caché de imágenes para Android. Usaremos la propiedad de Picasso para descargar imágenes para mostrar en una galería y mantenerlas en caché, para evitar hacer una segunda descarga para mantener la imagen en mayor resolución. Usando Huawei HiAI Image Super-Resolution para mejorar la calidad de imagen y mostrar estas imágenes con mejor calidad en una pantalla detallada.


Puedes obtener más información sobre la súper resolución de imagen de Huawei HiAI: https://developer.huawei.com/consumer/en/doc/20201101

**1.- Crea y registra una aplicación en AGC**
https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#0

**2.-Configura tu entorno de trabajo**
Instalar complementos de DevEco IDE
Click the File -> "Settings" -> "Plugins" -> "Browse repositories…"

Ingresa "DevEco IDE" para buscar el complemento e instalarlo.

**3.- Agregar biblioteca de dependencias**
Descarga el paquete vision-release.aar en los SDK de Huawei AI Engine de la comunidad de desarrolladores de Huawei.

Copia el paquete vision-release.aar descargado en el directorio app / libs del proyecto.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vyltizwf1y6u4wak23k3.png)

Puedes seguir:
https://developer.huawei.com/consumer/en/doc/development/hiai-Guides/20201103#h1-2-use-instructions
Agrega la dependencia de Picasso y HiIA Vision:

```
implementation(name: 'huawei-hiai-vision', ext: 'aar')
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.google.code.gson:gson:2.8.5'
```
**4.- Inicializar Huawei HiAi**
En la clase Application, cree una función initHiAi () e impleméntela en el método onCreate ()
```
private fun initHiAi() {
    VisionBase.init(applicationContext, object : ConnectionCallback {
        override fun onServiceConnect() {
            Log.i(TAG, "onServiceConnect")
        }
override fun onServiceDisconnect() {
            Log.i(TAG, "onServiceDisconnect")
        }
    })
}
```

**5.- Agregar RecyclerView**

En activity_main.xml agregamos un RecyclerView
```
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/galleryRecyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
```
**6.- Crea el Adaptador RecyclerView**
Crear la clase GalleryAdapter

```
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.Picasso
class GalleryAdapter(
    private val images: Array<String>,
    val itemClickListener: (String) -> Unit
) :
    RecyclerView.Adapter<GalleryAdapter.GalleryViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GalleryViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
        return GalleryViewHolder(view)
    }
override fun getItemCount(): Int {
        return images.size
    }
override fun onBindViewHolder(holder: GalleryViewHolder, position: Int) {
        val imageView = holder.galleryImageView
        Picasso.get()
            .load(images[position])
            .placeholder(R.drawable.logo)
            .error(R.drawable.logo_black)
            .into(imageView)
    }
inner class GalleryViewHolder(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        val galleryImageView: ImageView = itemView.findViewById(R.id.imageItemView)
init {
            galleryImageView.setOnClickListener {
                itemClickListener.invoke(images[adapterPosition])
            }
        }
    }
}
```
**7.- Crear administrador de superresolución de imágenes**
La superresolución de imágenes HiAI tiene una limitación, ya que solo puede tratar imágenes con una resolución igual o inferior a 800 * 600.

```
import android.content.Context
import android.graphics.Bitmap
import com.huawei.hiai.vision.image.sr.ImageSuperResolution
import com.huawei.hiai.vision.visionkit.common.Frame
import com.huawei.hiai.vision.visionkit.image.sr.SuperResolutionConfiguration
import java.util.concurrent.Executors
class HiAiImageSuperResolutionManager(applicationContext: Context) {
private var imageSuperResolution: ImageSuperResolution =
        ImageSuperResolution(applicationContext)
companion object {
        private const val THREADS_COUNT = 10
        private const val MAX_WIDTH = 800
        private const val MAX_HEIGHT = 600
    }
private val executor = Executors.newFixedThreadPool(THREADS_COUNT)
fun doSuperResolutionAsync(bitmap: Bitmap, onImageListener: (Bitmap?) -> Unit) {
        executor.execute {
            onImageListener.invoke(doSuperResolution(bitmap))
        }
    }
private fun doSuperResolution(source: Bitmap): Bitmap? {
        if (imageSuperResolution.prepare() != 0) return source
        return if (source.width <= MAX_WIDTH && source.height <= MAX_HEIGHT) {
            getSuperResolutionBitmap(source)
        } else {
            source
        }
    }
private fun getSuperResolutionBitmap(source: Bitmap): Bitmap? {
        val frame = Frame().apply {
            bitmap = source
        }
        val result = getSuperResolutionInstance().doSuperResolution(frame, null).bitmap
        return result
    }
private fun getSuperResolutionInstance(): ImageSuperResolution {
        val params = SuperResolutionConfiguration(
            SuperResolutionConfiguration.SISR_SCALE_3X,
            SuperResolutionConfiguration.SISR_QUALITY_HIGH
        )
        imageSuperResolution.setSuperResolutionConfiguration(params)
return imageSuperResolution
    }
}
```
**8.- Crear actividad de detalle**

DetailActivity mostrará la imagen almacenada en caché y la imagen que ha sido procesada y mejorada con HiAI Image Super-Resolution.

```
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.squareup.picasso.Picasso
import com.squareup.picasso.Target
import kotlinx.android.synthetic.main.activity_detail_gallery.*
@Suppress("DEPRECATION")
class DetailActivity : AppCompatActivity() {
companion object {
        private const val EXTRA_PHOTO_CACHE = "ExtraPhotoCache"
        private const val TAG = "UiAiDetailActivity"
    }
private lateinit var imageUrl: String
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_detail_gallery)
        imageUrl = intent.getStringExtra(EXTRA_PHOTO_CACHE).toString()
    }
override fun onStart() {
        super.onStart()
        Picasso.get()
            .load(imageUrl)
            .placeholder(R.drawable.logo)
            .error(R.drawable.logo_black)
            .into(object : Target {
                override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
                    Log.i(TAG, "onPrepareLoad")
                }
override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {
                    Log.i(TAG, "onBitmapFailed")
                }
override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
                    Log.i(TAG, "onBitmapLoaded")
                    if (bitmap != null) {
                        imageNoResolution.setImageBitmap(bitmap)
                        HiAiImageSuperResolutionManager(applicationContext).doSuperResolutionAsync(
                            bitmap
                        ) {
                            imageResolution.setImageBitmap(it)
                        }
                    }
                }
            })
    }
}
```
**9.- Implementa RecyclerView**

Instala y configura el adaptador en la vista del reciclador dentro de la Actividad principal

```
val images = resources.getStringArray(R.array.url_resources)
galleryRecyclerView.apply {
    this.setHasFixedSize(true)
    this.layoutManager = GridLayoutManager(this@MainActivity, 2)
    adapter = GalleryAdapter(images) { url ->
        val intent = Intent(this@MainActivity, DetailActivity::class.java).apply {
            this.putExtra("ExtraPhotoCache", url)
        }
        startActivity(intent)
    }
}
```
**10.- Ejecutar y probar**
Después de ejecutar la aplicación, la Actividad principal muestra la Galería, mostrando las imágenes descargadas en tamaño real.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rw13f9l3e4ov91jzdvvc.png)

Cuando haces clic en una imagen, la actividad de detalles muestra la misma imagen obtenida de la caché de Picasso en un contenedor más grande.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hw3h9odaumhemod6n1nj.png)
Como puede observar, la imagen superior está distorsionada, y la inferior después del procesamiento de superresolución de imagen HiAI muestra una imagen más clara y nítida.
Por lo tanto, podemos mejorar la experiencia del usuario mediante el uso de imágenes más pequeñas que lo hacen descargable y mejoran la experiencia del usuario.
Puedes descargar el proyecto:
https://github.com/jordanrsas/ImageSuperResolution