从gallery android位图向服务器发送图像

从gallery android位图向服务器发送图像,android,bitmap,compression,base64,android-gallery,Android,Bitmap,Compression,Base64,Android Gallery,我试图从gallery向服务器发送一个图像,我用Base64 我为gallery启动了一项活动: private void startGalleryActivity() { Intent intent = new Intent(); intent.setType("image/*"); String selectPicture = getResources().getString(R.string.select_picture); intent.setAction

我试图从gallery向服务器发送一个图像,我用
Base64

我为gallery启动了一项活动:

private void startGalleryActivity() {
    Intent intent = new Intent();
    intent.setType("image/*");
    String selectPicture = getResources().getString(R.string.select_picture);
    intent.setAction(Intent.ACTION_GET_CONTENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    startActivityForResult(intent, GALLERY);
}
我在ActivityResult的
中收到了结果:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == GALLERY && resultCode == MainActivity.RESULT_OK) {
        Uri pickedImage = data.getData();

        // Let's read picked image path using content resolver
        String[] filePath = {MediaStore.Images.Media.DATA};
        Cursor cursor = getContentResolver().query(pickedImage, filePath, null, null, null);
        cursor.moveToFirst();
        String imagePath = cursor.getString(cursor.getColumnIndex(filePath[0]));

        // Now we need to set the GUI ImageView data with data read from the picked file.
        imageView.setImageBitmap(BitmapFactory.decodeFile(imagePath));

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;


        bitmap = BitmapFactory.decodeFile(imagePath, options);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
        byte[] byteArray = byteArrayOutputStream .toByteArray();

        String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);

        Server s = new Server("new");
        s.send(encoded);

        // At the end remember to close the cursor or you will end with the RuntimeException!
        cursor.close();
    }
    super.onActivityResult(requestCode, resultCode, data);

当我发送图像服务的大小是它的4倍以上。如果我在读过图像后再写,这是用两倍大小写的。为什么我会有这样的开销?

它将大约大37%:

非常粗略地说,Base64编码的二进制数据的最终大小等于 原始数据大小的1.37倍

资料来源:

为什么我有这个开销

除了Base64开销之外,您还将图像重新编码为PNG。如果图像以其他形式开始,例如JPEG,则该图像的PNG版本可能会大很多

另外,请删除前面的四行
//让我们使用内容解析器读取拾取的图像路径
。首先,该代码将在数亿台Android设备上失败,因为,而且您不能假设您可以获得该数据的本地文件系统路径。其次,您不需要它,因为
BitmapFactory
有一个
decodeStream()
方法,可以与
getContentResolver().openInputStream(PickeImage)
一起使用


此外,请不要在
BitmapFactory
上调用
decode…()
两次。加载位图一次。将位图用于
图像视图和上载。

在PNG上调用compress不会使文件变小,因为它已经被压缩。将二进制文件转换为文本流 这会让它变得更大。通过转换PNG文件避免更少的开销 要发送文本文件,只需按原样发送文件,作为字节数组。并添加文件长度 在标题中。您可以使用DataOutputStream来执行此操作

byte[] byteArray = byteArrayOutputStream .toByteArray();

ByteArrayOutputStream btOS = new ByteArrayOutputStream();
DataOutputStream dataOS = new DataOutputStreamEx(btOS);

dataOS.writeInt(byteArray.length); // length of file
dataOS.write(byteArray);           // actual file
dataOS.write(0);                   // end of field
dataOS.close()
我不知道你在后台使用的是什么,但是你可以直接阅读 您将接收的内容的前4个字节,即长度
你的档案。并使用该长度读取整个文件。

您正在使用位图和BitmapFactory将小jpg文件转换为大png文件。你为什么不直接发送jpg?因此,不要使用位图和位图工厂开始。你最后得到的东西不是你的档案