Android — Загрузка bmp на сервер с использованием составных сбоев

#android #retrofit #multipart

#Android #переоборудование #составная часть

Вопрос:

Я пытаюсь загрузить bmp-файл на сервер (аватар). Для этого я подаю в суд на Модернизацию и Составные части. Вот часть дооснащения :

 @Multipart  @POST("api/media/images")  suspend fun uploadImage(  @Part file: MultipartBody.Part?  ): UploadImageResponse  

Пользователи выбирают одно изображение из галереи, а затем приложение должно загрузить его на сервер. Я использую jetpack compose в этом приложении. Вот мой компонент для выбора фотографии :

 @Composable fun UploadButton(bitmapSelected: MutableStatelt;Bitmap?gt;) {   var imageUri by remember {  mutableStateOflt;Uri?gt;(null)  }   val context = LocalContext.current   val launcher = rememberLauncherForActivityResult(  contract =  ActivityResultContracts.GetContent()  ) { uri: Uri? -gt;  imageUri = uri  }   Column(  modifier = Modifier  .width(72.dp),  horizontalAlignment = Alignment.CenterHorizontally,  verticalArrangement = Arrangement.Top  ) {  IconButton(  modifier = Modifier  .clip(CircleShape)  .size(48.dp)  .background(Color.Black),  onClick = { launcher.launch("image/*") })  {  imageUri?.let { it -gt;  if (Build.VERSION.SDK_INT lt; 28) {  bitmapSelected.value = MediaStore.Images  .Media.getBitmap(context.contentResolver, it)   } else {  val source = ImageDecoder  .createSource(context.contentResolver, it)  bitmapSelected.value = ImageDecoder.decodeBitmap(source)  bitmapSelected.value = ImageDecoder.decodeBitmap(source)  }  bitmapSelected.value?.let { btm -gt;  Image(  bitmap = btm.asImageBitmap(),  contentDescription = null,  modifier = Modifier.size(40.dp),  contentScale = ContentScale.Crop  )  }  }  Spacer(modifier = Modifier.height(PaddingSmall))  }  Text(  textAlign = TextAlign.Center,  text = stringResource(R.string.upload_profile_photo),  style = MaterialTheme.typography.body2,  color = Color.Black  )  } }  

как вы можете видеть, состояние передается в класс Screen Composable при использовании выбранного bmp:

 @Composable fun CreateAccountScreen(  navController: NavController,  viewModel: CreateAccountViewModel = hiltViewModel() ) { ... val bitmap = remember {mutableStateOflt;Bitmap?gt;(null) }  UploadButton( bitmapSelected = bitmap )  

Все работает отлично. Вы можете выбрать фотографию и установить ее в качестве аватара. Однако , когда я хочу отправить фотографию как часть в бэкэнд, как это :

 fun bitmapToMultipart(imageBitmap: Bitmap): MultipartBody.Part {  val bos = ByteArrayOutputStream()  imageBitmap.compress(Bitmap.CompressFormat.JPEG, 80 /*ignored for PNG*/, bos)  val bitmapdata = bos.toByteArray()  Log.i(TAG, "bitmapToMultipart: ${Base64.encodeToString(bitmapdata,Base64.NO_WRAP)}")   val name: RequestBody = bitmapdata.toRequestBody("image/*".toMediaTypeOrNull(), 0, bitmapdata.size)  return MultipartBody.Part.createFormData("file", "avatar", name) }  

Я получаю сообщение об ошибке с сервера, что это не изображение. Что может быть не так ? В чем проблема ?

Комментарии:

1. Попробуйте использовать конкретный тип MIME, а не подстановочный знак ( image/* ).

2. Не могли бы вы показать мне пример, пожалуйста ?

3. Вы кодируете свое изображение в формате JPEG ( imageBitmap.compress(Bitmap.CompressFormat.JPEG, 80 /*ignored for PNG*/, bos) ). Тип MIME для JPEG image/jpeg -нет image/* .

4. val bitmapdata = bos.toByteArray() ? Или val jpgdata = bos.toByteArray() ? Вы загружаете не растровое изображение, а файл jpg.

Ответ №1:

Решенный. Мне пришлось добавить .jpg в имя файла, чтобы оно было :

 return MultipartBody.Part.createFormData("file", "avatar.jpg", name)