kotlin 如何使用Ktor客户端获取请求获取图像/png?

fzwojiic  于 2023-03-13  发布在  Kotlin
关注(0)|答案(3)|浏览(246)

我正在尝试从客户端向服务器发出get请求。服务器用image/png内容类型响应。我如何从我的Kotlin代码中接收图像?

mnemlml8

mnemlml81#

您不仅可以下载图像,还可以下载任何其他文件。
像往常一样创建ktor-client

val client = HttpClient(OkHttp) {
    install(ContentNegotiation) {
        json(Json { isLenient = true; ignoreUnknownKeys = true })
    }
}

要使用client下载文件,请使用bodyAsChannel()读取response,它将响应读取为ByteReadChannel。使用copyAsChannel()将数据写入磁盘,并传递目标的ByteWriteChannel

GlobalScope.launch(Dispatchers.IO) {
    val url = Url("FILE_DOWNLOAD_LINK")
    val file = File(url.pathSegments.last())
    client.get(url).bodyAsChannel().copyAndClose(file.writeChannel())
    println("Finished downloading..")
}
2wnc66cl

2wnc66cl2#

如果不需要将图像保存在存储器中,可以使用byteArray内存源对图像进行解码。
如果预期图像较大,最好在解码前将其缩小,请参阅此处(Android)Android: BitmapFactory.decodeStream() out of memory with a 400KB file with 2MB free heap
还要注意,Ktor API经常在版本之间变化,在本示例中使用的是ktor_version = '2.0.0'

val client = HttpClient(Android) { install(Logging) { level = LogLevel.ALL } }

suspend fun getBitmap(uri: Uri): Bitmap? {
    return runCatching {
        val byteArray = withContext(Dispatchers.IO) {
            client.get(Url(uri.toString())).readBytes()
        }

        return withContext(Dispatchers.Default) {
            ByteArrayInputStream(byteArray).use {
                val option = BitmapFactory.Options()
                option.inPreferredConfig = Bitmap.Config.RGB_565 // To save memory, or use RGB_8888 if alpha channel is expected 
                BitmapFactory.decodeStream(it, null, option)
            }
        }
    }.getOrElse {
        Log.e("getBitmap", "Failed to get bitmap ${it.message ?: ""}" )
        null
    }
}
cuxqih21

cuxqih213#

您可能希望从Ktor服务器提供 * 静态内容 *:https://ktor.io/docs/serving-static-content.html
创建一个静态文件夹,然后将图像放入其中:

static("/") {
    staticRootFolder = File("files")
}

设置好后,你就可以引用该文件夹中的文件了。如果你还想引用子文件夹中的文件,你可以添加一个额外的files(".")行:

static("/") {
    staticRootFolder = File("files")
    files(".")
}

相关问题