从图库android位图发送图像到服务器

时间:2015-05-17 21:56:27

标签: android bitmap compression base64 android-gallery

我尝试从图库向服务器发送图片,我用Base64对其进行了压缩 我开始为画廊开展一项活动:

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);
}

我收到了onActivityResult的结果:

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倍。如果我在读完之后写了图像,这是双倍大小的写入。为什么我有这个开销?

4 个答案:

答案 0 :(得分:2)

  

为什么我会有这个开销?

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

另外,请删除前面带有// Let's read picked image path using content resolver的四行。首先,该代码将在数以亿计的Android设备上失败,因为{{3}},您不能假设您可以获得该数据的本地文件系统路径。其次,您不需要它,因为BitmapFactory有一个decodeStream()方法可以与getContentResolver().openInputStream(pickedImage)一起使用。

此外,请勿在{{1​​}}上致电decode...()两次。加载位图一次。将位图用于BitmapFactory和上传。

答案 1 :(得分:1)

在PNG上调用压缩不会使文件变小,因为它已经被压缩了。将二进制文件转换为文本流 真的会变得很大。通过转换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个字节,这将是长度 你的文件。并使用该长度来读取整个文件。

答案 2 :(得分:0)

它将增加约37%:

  

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

来源:http://en.wikipedia.org/wiki/Base64

答案 3 :(得分:0)

您正在使用Bitmap和BitmapFactory将小型jpg文件转换为大型png文件。你为什么不直接发送jpg?所以不要使用Bitmap和BitmapFactory开头。你最后得到的东西不是你的文件。