在使用 Retrofit2 上传到服务器之前调整图像文件的大小
Resize image file before uploading to server using Retrofit2
我正在尝试使用 Retrofit 将图像上传到服务器,但现在我遇到了图像尺寸太大的问题。
这是我的代码:
private fun uploadImageFileToApiServer(){
Log.e("api", "start")
var file: File?= null
try{
file = File(Common.getFilePath(this, selectedUri!!))
Log.e("FilePath", file.toString())
}catch(e: URISyntaxException) {e.printStackTrace()}
if(file != null)
{
val requestBody = ProgressRequestBody(file, this)
//how can i resize the image here before uploading it to server???
val body = MultipartBody.Part.createFormData("image", file.name, requestBody)
Thread(Runnable {
mService.uploadFile(body)
.enqueue(object: Callback<String> {
override fun onFailure(call: Call<String>, t: Throwable) {
Toast.makeText(this@ApiProcessing, t.message, Toast.LENGTH_LONG).show()
Log.e("api", t.message!!)
}
override fun onResponse(call: Call<String>, response: Response<String>) {
val stringResponse = response.body()?.toString()
try {
val jsonObject = JSONObject(stringResponse)
val label = jsonObject.getString("label")
val width = jsonObject.getString("width")
val height = jsonObject.getString("height")
HaveFruitResult.label = label
HaveFruitResult.width = width
HaveFruitResult.height = height
}
catch (e: NullPointerException){
Toast.makeText(this@ApiProcessing, e.message, Toast.LENGTH_LONG).show()
//moveToMainActivity()
val handler = Handler()
handler.postDelayed({
moveToMainActivity()
}, 4000)
}
}
})
}).start()
}
else
{
Toast.makeText(this@ApiProcessing, "Fail!!", Toast.LENGTH_LONG).show()
}
Log.e("api", "end")
}
因为图片太大,上传需要很长时间,所以有时我无法从API服务器取回响应。
这是我的 IUploadAPI
interface IUploadAPI {
@Multipart
@POST("/fruit_vision_api")
fun uploadFile(@Part file: MultipartBody.Part) : Call<String>
}
我该如何解决这个问题?
非常感谢您的帮助!!!!!!!!!!
我正在使用此对象将图像压缩到最大 1Mo。您可以使用它或根据您的需要调整它
/**
* Definition of the BitmapUtils object.
*/
object BitmapUtils {
const val ONE_KO = 1024
const val ONE_MO = ONE_KO * ONE_KO
/**
* Compress, if needed, an image file to be lower than or equal to 1 Mo
*
* @param filePath Image file path
*
* @return Stream containing data of the compressed image. Can be null
*/
fun compressedImageFile(filePath: String): InputStream? {
var quality = 100
var inputStream: InputStream? = null
if (filePath.isNotEmpty()) {
var bufferSize = Integer.MAX_VALUE
val byteArrayOutputStream = ByteArrayOutputStream()
try {
val bitmap = BitmapFactory.decodeFile(filePath)
do {
if (bitmap != null) {
byteArrayOutputStream.reset()
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream)
bufferSize = byteArrayOutputStream.size()
logD { "quality: $quality -> length: $bufferSize" }
quality -= 10
}
} while (bufferSize > ONE_MO)
inputStream = ByteArrayInputStream(byteArrayOutputStream.toByteArray())
byteArrayOutputStream.close()
} catch (e: Exception) {
logE { "Exception when compressing file image: ${e.message}" }
}
}
return inputStream
}
}
要从 InputStream 创建文件,您可以使用此扩展名:
fun File.copyInputStreamToFile(inputStream: InputStream) {
this.outputStream().use { fileOut ->
inputStream.copyTo(fileOut)
}
}
并使用它:
var file = File(YOUR_PATH)
file.copyInputStreamToFile(BitmapUtil.compressedImageFile(filePath))
我正在尝试使用 Retrofit 将图像上传到服务器,但现在我遇到了图像尺寸太大的问题。 这是我的代码:
private fun uploadImageFileToApiServer(){
Log.e("api", "start")
var file: File?= null
try{
file = File(Common.getFilePath(this, selectedUri!!))
Log.e("FilePath", file.toString())
}catch(e: URISyntaxException) {e.printStackTrace()}
if(file != null)
{
val requestBody = ProgressRequestBody(file, this)
//how can i resize the image here before uploading it to server???
val body = MultipartBody.Part.createFormData("image", file.name, requestBody)
Thread(Runnable {
mService.uploadFile(body)
.enqueue(object: Callback<String> {
override fun onFailure(call: Call<String>, t: Throwable) {
Toast.makeText(this@ApiProcessing, t.message, Toast.LENGTH_LONG).show()
Log.e("api", t.message!!)
}
override fun onResponse(call: Call<String>, response: Response<String>) {
val stringResponse = response.body()?.toString()
try {
val jsonObject = JSONObject(stringResponse)
val label = jsonObject.getString("label")
val width = jsonObject.getString("width")
val height = jsonObject.getString("height")
HaveFruitResult.label = label
HaveFruitResult.width = width
HaveFruitResult.height = height
}
catch (e: NullPointerException){
Toast.makeText(this@ApiProcessing, e.message, Toast.LENGTH_LONG).show()
//moveToMainActivity()
val handler = Handler()
handler.postDelayed({
moveToMainActivity()
}, 4000)
}
}
})
}).start()
}
else
{
Toast.makeText(this@ApiProcessing, "Fail!!", Toast.LENGTH_LONG).show()
}
Log.e("api", "end")
}
因为图片太大,上传需要很长时间,所以有时我无法从API服务器取回响应。 这是我的 IUploadAPI
interface IUploadAPI {
@Multipart
@POST("/fruit_vision_api")
fun uploadFile(@Part file: MultipartBody.Part) : Call<String>
}
我该如何解决这个问题? 非常感谢您的帮助!!!!!!!!!!
我正在使用此对象将图像压缩到最大 1Mo。您可以使用它或根据您的需要调整它
/**
* Definition of the BitmapUtils object.
*/
object BitmapUtils {
const val ONE_KO = 1024
const val ONE_MO = ONE_KO * ONE_KO
/**
* Compress, if needed, an image file to be lower than or equal to 1 Mo
*
* @param filePath Image file path
*
* @return Stream containing data of the compressed image. Can be null
*/
fun compressedImageFile(filePath: String): InputStream? {
var quality = 100
var inputStream: InputStream? = null
if (filePath.isNotEmpty()) {
var bufferSize = Integer.MAX_VALUE
val byteArrayOutputStream = ByteArrayOutputStream()
try {
val bitmap = BitmapFactory.decodeFile(filePath)
do {
if (bitmap != null) {
byteArrayOutputStream.reset()
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream)
bufferSize = byteArrayOutputStream.size()
logD { "quality: $quality -> length: $bufferSize" }
quality -= 10
}
} while (bufferSize > ONE_MO)
inputStream = ByteArrayInputStream(byteArrayOutputStream.toByteArray())
byteArrayOutputStream.close()
} catch (e: Exception) {
logE { "Exception when compressing file image: ${e.message}" }
}
}
return inputStream
}
}
要从 InputStream 创建文件,您可以使用此扩展名:
fun File.copyInputStreamToFile(inputStream: InputStream) {
this.outputStream().use { fileOut ->
inputStream.copyTo(fileOut)
}
}
并使用它:
var file = File(YOUR_PATH)
file.copyInputStreamToFile(BitmapUtil.compressedImageFile(filePath))