Base64 编码省略最后 2 个字节
Base64 encoding omits final 2 bytes
此代码将位图编码为 Base64。出于调试目的,我还编写了几行代码将所有数据放入普通文件中。问题是文件不同:
直接从位图保存的文件:
DB 5A C4 80 00 00
从解码的 b64 数据中保存的文件:
DB 5A C4 80
所以在 encode/decode 2 字节 MIA 之后 正确的文件是第一个,因为它可以很容易地被 chrome、图像查看器等打开。我的代码:
Bitmap exportedBitmap = Bitmap.createBitmap(EXPORTED_IMAGE_SIZE, EXPORTED_IMAGE_SIZE, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(exportedBitmap);
float imageViewRatio = EXPORTED_IMAGE_SIZE / (float) getWidth();
canvas.save();
canvas.scale(imageViewRatio, imageViewRatio);
drawPhoto(canvas, mScale);
canvas.restore();
ByteArrayOutputStream outStream = new ByteArrayOutputStream(512000);
Base64OutputStream base64OutputStream = new Base64OutputStream(outStream, Base64.DEFAULT);
String timeString = new Date().toString();
File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "origin"+ timeString +".webp");
if (!outputFile.exists())
{
outputFile.delete();
}
outputFile.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
TeeOutputStream teeOutputStream = new TeeOutputStream(base64OutputStream, fileOutputStream);
exportedBitmap.compress(Bitmap.CompressFormat.WEBP, 85, teeOutputStream);
getContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(outputFile)));
exportedBitmap.recycle();
teeOutputStream.flush();
String outString = outStream.toString();
teeOutputStream.close();
decodeDataToFile(timeString, outString);
以及保存解码文件的方法(仅供参考-在不同平台后端服务上结果也是错误的):
private void decodeDataToFile(String pTimeString, String pOutString) throws IOException
{
File decodedFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "processed" + pTimeString + ".webp");
decodedFile.createNewFile();
FileOutputStream decodedFileOutputStream = new FileOutputStream(decodedFile);
decodedFileOutputStream.write(Base64.decode(pOutString, Base64.DEFAULT));
decodedFileOutputStream.flush();
decodedFileOutputStream.close();
getContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(decodedFile)));
}
我找到了解决方案 - 这是答案:Android File To Base64 using streaming sometimes missed 2 bytes
简而言之 - 在使用编码 byte[] / String
做更多事情之前需要 base64OutputStream.close();
此代码将位图编码为 Base64。出于调试目的,我还编写了几行代码将所有数据放入普通文件中。问题是文件不同: 直接从位图保存的文件:
DB 5A C4 80 00 00
从解码的 b64 数据中保存的文件:
DB 5A C4 80
所以在 encode/decode 2 字节 MIA 之后 正确的文件是第一个,因为它可以很容易地被 chrome、图像查看器等打开。我的代码:
Bitmap exportedBitmap = Bitmap.createBitmap(EXPORTED_IMAGE_SIZE, EXPORTED_IMAGE_SIZE, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(exportedBitmap);
float imageViewRatio = EXPORTED_IMAGE_SIZE / (float) getWidth();
canvas.save();
canvas.scale(imageViewRatio, imageViewRatio);
drawPhoto(canvas, mScale);
canvas.restore();
ByteArrayOutputStream outStream = new ByteArrayOutputStream(512000);
Base64OutputStream base64OutputStream = new Base64OutputStream(outStream, Base64.DEFAULT);
String timeString = new Date().toString();
File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "origin"+ timeString +".webp");
if (!outputFile.exists())
{
outputFile.delete();
}
outputFile.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
TeeOutputStream teeOutputStream = new TeeOutputStream(base64OutputStream, fileOutputStream);
exportedBitmap.compress(Bitmap.CompressFormat.WEBP, 85, teeOutputStream);
getContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(outputFile)));
exportedBitmap.recycle();
teeOutputStream.flush();
String outString = outStream.toString();
teeOutputStream.close();
decodeDataToFile(timeString, outString);
以及保存解码文件的方法(仅供参考-在不同平台后端服务上结果也是错误的):
private void decodeDataToFile(String pTimeString, String pOutString) throws IOException
{
File decodedFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "processed" + pTimeString + ".webp");
decodedFile.createNewFile();
FileOutputStream decodedFileOutputStream = new FileOutputStream(decodedFile);
decodedFileOutputStream.write(Base64.decode(pOutString, Base64.DEFAULT));
decodedFileOutputStream.flush();
decodedFileOutputStream.close();
getContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(decodedFile)));
}
我找到了解决方案 - 这是答案:Android File To Base64 using streaming sometimes missed 2 bytes
简而言之 - 在使用编码 byte[] / String
base64OutputStream.close();