将图像存储到 Android Q 与以前版本不同的字节数
Different number of bytes when storing images to Android Q vs previous versions
我们有一个我们不完全理解的情况。在我们的应用程序中,用户选择图像,这些图像保存到光盘并映射到他们的图片文件夹。然后当用户准备上传选择的图片时,我们使用 ByteArrayOutputStream
将它们每一张都变成一个字节数组,然后再变成一串十六进制字符。到目前为止,即使在数据覆盖率低的地区,这种方法也很有效。
我们将图像保存到光盘的过程(为清晰起见,通常在 Stack Overflow 中找到)是:
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
imageDir = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "temp", null);
bytes.close();
由于 MediaStore.Images.Media.insertImage
已被弃用,我们已开始查看 Android Q 及更高版本的代码:
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, "location_image.jpg");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
Uri uri = inContext.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
OutputStream imageOutStream = inContext.getContentResolver().openOutputStream(uri);
imageDir = String.valueOf( uri );
Boolean b = inImage.compress(Bitmap.CompressFormat.JPEG, 100, imageOutStream);
imageOutStream.close();
但是,当我们使用ByteArrayOutputStream
上传Q及以上新进程存储的图片时,数组有3-4那么大,这反过来又打乱了我们的数据上传过程。例如,在旧进程 (=Q) 中它膨胀到 1.4M。
这是为什么?
我们可以将新流程中的 JPEG 质量降低到 80-90%,并将获得与旧流程相同长度的字节数组。
@Mike M 在以上评论中提供的答案。
insertImage
始终将质量设置为 50%,较新的代码只需匹配:
Boolean b = inImage.compress(Bitmap.CompressFormat.JPEG, 50, imageOutStream);
也最好删除旧的(已弃用的)代码:
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
因为它没有实际功能。
在这两种情况下,某些型号 运行 Android 10 non-unique 图像标题可能存在问题。所以它有助于将它们更改为:
"image_" + System.currentTimeMillis()+".jpg"
我们有一个我们不完全理解的情况。在我们的应用程序中,用户选择图像,这些图像保存到光盘并映射到他们的图片文件夹。然后当用户准备上传选择的图片时,我们使用 ByteArrayOutputStream
将它们每一张都变成一个字节数组,然后再变成一串十六进制字符。到目前为止,即使在数据覆盖率低的地区,这种方法也很有效。
我们将图像保存到光盘的过程(为清晰起见,通常在 Stack Overflow 中找到)是:
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
imageDir = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "temp", null);
bytes.close();
由于 MediaStore.Images.Media.insertImage
已被弃用,我们已开始查看 Android Q 及更高版本的代码:
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, "location_image.jpg");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
Uri uri = inContext.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
OutputStream imageOutStream = inContext.getContentResolver().openOutputStream(uri);
imageDir = String.valueOf( uri );
Boolean b = inImage.compress(Bitmap.CompressFormat.JPEG, 100, imageOutStream);
imageOutStream.close();
但是,当我们使用ByteArrayOutputStream
上传Q及以上新进程存储的图片时,数组有3-4那么大,这反过来又打乱了我们的数据上传过程。例如,在旧进程 (=Q) 中它膨胀到 1.4M。
这是为什么?
我们可以将新流程中的 JPEG 质量降低到 80-90%,并将获得与旧流程相同长度的字节数组。
@Mike M 在以上评论中提供的答案。
insertImage
始终将质量设置为 50%,较新的代码只需匹配:
Boolean b = inImage.compress(Bitmap.CompressFormat.JPEG, 50, imageOutStream);
也最好删除旧的(已弃用的)代码:
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
因为它没有实际功能。
在这两种情况下,某些型号 运行 Android 10 non-unique 图像标题可能存在问题。所以它有助于将它们更改为:
"image_" + System.currentTimeMillis()+".jpg"