如何使用 Retrofit/Android 将位图发布到服务器



我正在尝试使用AndroidRetrofit将位图发布到服务器。

目前我知道如何发布文件,但我更喜欢直接发送位图。

这是因为用户可以从其设备上选择任何图像。我想在发送到服务器之前调整它的大小以节省带宽,并且最好不必加载它,调整它的大小,将其保存为文件到本地存储,然后发布文件。

有人知道如何从Retrofit发布位图吗?

注意:在 Main 以外的其他线程上进行此转换。RxJava可以帮助实现这一目标,或者协程

首先将位图转换为文件

//create a file to write bitmap data
File f = new File(context.getCacheDir(), filename);
f.createNewFile();
//Convert bitmap to byte array
Bitmap bitmap = your bitmap;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 0 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
//write the bytes in file
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
fos.write(bitmapdata);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}

之后,使用Multipart创建请求以上传您的文件

RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), f);
MultipartBody.Part body = MultipartBody.Part.createFormData("upload", f.getName(), reqFile);

您的服务呼叫应如下所示

interface Service {
@Multipart
@POST("/yourEndPoint")
Call<ResponseBody> postImage(@Part MultipartBody.Part image);
}

然后只需调用您的 API

Service service = new Retrofit.Builder().baseUrl("yourBaseUrl").build().create(Service.class);
Call<okhttp3.ResponseBody> req = service.postImage(body);
req.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { 
// Do Something with response
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
//failure message
t.printStackTrace();
}
});

建议通过文件上传位图/图像。图像应保存在设备存储中,然后,您应该以多部分形式发送文件。但是,如果您需要不将位图/图像存储在存储中并通过 Retrofit 直接上传,那么您可以这样做。

  1. 获取位图并将其转换为字节数组(字节[](
  2. 转换 Base64
  3. 中的 byte[](Base64 将是单个字符串(
  4. 像上传常规字符串一样上传 Base64 字符串

当您需要在应用程序或后端显示图像时。将 base64 转换为字节,将字节转换为位图并显示位图。

将位图转换为字节[]

public static byte[] bitmapToBytes(Bitmap photo) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
return stream.toByteArray();
}

将字节 [] 转换为 Base64 字符串

public static String bytesToBase64(byte[] bytes) {
final String base64 = Base64.encodeToString(bytes, 0);
return base64;
}

将 Base64 字符串转换为字节[]

public static byte[] base64ToBytes(String base64) {
final byte[] bytes = Base64.decode(base64, 0);
return bytes;
}

将字节 [] 转换为位图

public static Bitmap bytesToBitmap(byte[] bytes) {
final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
return bitmap;
}

我见过有人上传这样的图像,但我个人更喜欢通过文件上传。

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();

您可以将位图转换为字节数组,然后将此字节数组发布到服务器后,例如,您可以制作一个临时文件

File file = new File(this.getCacheDir(), filename);

文件直接更新到服务器中

最新更新