简体   繁体   English

将图像从 Android 上传到仅接受 JPEG 和 PNG 的服务器

[英]Upload image from Android to Server that accepts only JPEG and PNG

MediaStore.Images.Media.Data is deprecated so I tried using byte array, but my server throws an error that it accepts only file types of jpeg and png. MediaStore.Images.Media.Data 已弃用,所以我尝试使用字节数组,但我的服务器抛出一个错误,它只接受 jpeg 和 png 文件类型。 I have read @commonsware's answers a couple of times from other questions but I can't seem to get it right.我已经从其他问题中多次阅读了@commonsware 的回答,但我似乎无法理解。 How do I get the file type and also the image so it can be attached to my network call?如何获取文件类型和图像,以便将其附加到我的网络呼叫中? Thanks in advance提前致谢

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode == RESULT_OK && requestCode == PROFILE_REQUEST_CODE) {
            val uri = data?.data
            createImageData(uri)
            profile_image.setImageURI(data?.data)
        }
    }
 private fun createImageData(uri: Uri?) {
        val inputStream = activity?.contentResolver?.openInputStream(uri!!)
        processImage(inputStream)
    }

    private fun processImage(inputStream: InputStream?) {
        imageData = inputStream?.readBytes()
        bitmap = BitmapFactory.decodeStream(inputStream)
        val imageBody: RequestBody = RequestBody.create(MediaType.parse("multipart/form-data"), imageData!!)
        val image: MultipartBody.Part = MultipartBody.Part.createFormData("image", "user", imageBody)
        uploadImage(image)
    }

    private fun uploadImage(image: MultipartBody.Part) {
        val user = appPreferences?.getUser()
        val userToken = user?.jwt_token
        val token = "Bearer $userToken"
        val headers = HashMap<String, String>()

        //headers["Authorization"] = token
        val uploadResponseCall: Call<ProfileImageResponse> = client.getApi().upload(token, image)
        uploadResponseCall.enqueue(object : retrofit2.Callback<ProfileImageResponse> {
            override fun onResponse(call: Call<ProfileImageResponse>, response: Response<ProfileImageResponse>) {
                val imageResponse = response.body()
                val resCode = imageResponse?.statuscode
                val msg = imageResponse?.message
                if (resCode == 200) {
                    appUtils.showSnackBar(requireActivity().applicationContext, profile_frame, msg!!)
                } else {
                    appUtils.showSnackBar(requireActivity().applicationContext, profile_frame, "wrong file type")
                }
            }

            override fun onFailure(call: Call<ProfileImageResponse>, t: Throwable) {
                if (t is IOException) {
                    call.cancel()
                    Log.d("profilefragment", "issue")
                    appUtils.showSnackBar(requireActivity().applicationContext, profile_frame, "server error")
                }
            }
        })

    }

Try to add an appropriate Content-Type header.尝试添加适当的 Content-Type 标头。 image/png or image/jpg should fit. image/pngimage/jpg应该适合。 Also, it possibly, should not be the multipart request.此外,它可能不应该是多部分请求。 So you'll need such kind of request.所以你需要这样的请求。

private fun processImage(inputStream: InputStream?) {
        imageData = inputStream?.readBytes()
        bitmap = BitmapFactory.decodeStream(inputStream)
        val imageBody: RequestBody = imageData!.toRequestBody() 
        uploadImage(imageBody)
}

or if it's really should be multipart/form-data, you should correctly set mime type for the image part like this:或者如果它真的应该是 multipart/form-data,你应该像这样正确设置图像部分的 MIME 类型:

 private fun processImage(inputStream: InputStream?) {
        imageData = inputStream?.readBytes()
        bitmap = BitmapFactory.decodeStream(inputStream)
        val imageBody: RequestBody = RequestBody.create(MediaType.parse("image/png"), imageData!!)
        val image: MultipartBody.Part = MultipartBody.Part.createFormData("image", "user", imageBody)
        uploadImage(image)
}

Here is example这是例子

  @Multipart
    @POST(ApiConstants.SIGNUP)
    fun signUp(
        @Query("first_name") firstName: String,
        @Query("last_name") lastName: String,
        @Query("email") email: String,
        @Query("password") password: String,
        @Query("gender") gender: String,
        @Query("phone_code") phoneCode: String,
        @Query("phone_no") phoneNo: String,
        @Part("id_card_front\"; filename=\"pp.png") id_card_front: RequestBody?
) :  Observable<SignUpModel>

Here is usage这是用法

var image = RequestBody.create(
                MediaType.parse("image/*"),
                getFileFromBitmap((imageview.drawable as BitmapDrawable).bitmap, 13)
            )
    disposable = retroClient.signUp(
                fname,
                lname,
                email,
                password,
                gender,
                phoneCode,
                phone,
                image,

            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ result ->
                    Log.d("response", result.toString())

                }, { error ->

                    Log.e("error", error.toString())
                })

the method is used to get file from bitmap该方法用于从位图获取文件

 fun getFileFromBitmap(bitmap: Bitmap, index: Int): File {
        val f = File(cacheDir, "something+$index")
        f.createNewFile()
        val bitmap = bitmap
        bitmap
        val bos = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG, 25 /*ignored for PNG*/, bos)
        val bitmapdata = bos.toByteArray()
        val fos = FileOutputStream(f)
        fos.write(bitmapdata)
        fos.flush()
        fos.close()

        return f
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM