将Android图片进行base64编码/解码为字符串

3

好的,我已经阅读了关于这个主题的所有问题和答案。我已经读了几天,但是没有一个方法对我有效,所以我有一个直接的问题。这段代码生成一个字符串。

public String getStringImage(Bitmap bmp){
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] imageBytes = baos.toByteArray();
    input = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return input;
}

这段代码可以从同一图片中生成另一个字符串,
  <?php

$data = file_get_contents('Lake_mapourika_NZ.jpeg');
$nova = base64_encode($data);

    echo $nova;

?>

当我在Java中将它们插入到这段代码中时:
  public void decodeImage()
{
    byte[] decodedByte = Base64.decode(input, Base64.DEFAULT);
    bitmap = BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
    imageView.setImageBitmap(bitmap);
}

第一个字符串不起作用,第二个可以正常工作。为什么?为什么Java到Java不起作用,而PHP到Java可以正常工作?

当然,这两个字符串是不同的,这也是一个好问题。为什么它们从相同的位图生成时不同?对我来说,Java解码工作得很好,但编码不起作用。

我正在使用此代码将我的图片从应用程序发送到服务器,因此我不能每次都使用在线转换器进行编码。我没有收到任何错误消息,对于使用手机相机拍摄的图片,我会遇到内存不足异常。但是当将质量更改为50时,我会得到解码后的字符串,但它无法像通常那样工作。

是否有其他方法可以实现?


1
我可以问一下你为什么在这里使用base64吗? - e4c5
input 应该是一个本地变量,String input = ...。这并不能解释错误,因此将字节保存到文件中,以查看 compress 是否有效。也许在 ?> 后面会跟着一个换行符(通常是错误的),那么 Java 也需要一个显式的换行符 "\r\n" - Joop Eggen
我正在尝试与我创建的WordPress网站同步,以便当用户从应用程序(手机平板电脑)上传图片时,它需要上传到WordPress网站的图像文件夹中。@e4c5 - cfhpanteracfh
你认为这个URL怎么样?当那张图片在我的手机上时呢?@cwfei - cfhpanteracfh
那么为什么需要将图像转换为base64格式才能上传呢? - e4c5
显示剩余3条评论
2个回答

2

你的代码中出现了错误,但不是你发布的那部分代码。 请检查你编码的位图内容,并检查你在解码时是否使用了正确的输入字符串变量。

你的编码和解码部分都很好。如果你不依赖成员字段,那么这段代码会更好。

public String getStringImage(Bitmap bmp)
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] imageBytes = baos.toByteArray();
    String input = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return input;
}

public void decodeImage(ImageView iv, String input)
{
    byte[] decodedByte = Base64.decode(input, Base64.DEFAULT);
    Bitmap bitmap = BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
    iv.setImageBitmap(bitmap);
}

测试上述编码/解码方法的代码-修改为使用参数而不是成员字段。

Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.thn);
ImageView iv = (ImageView)findViewById(R.id.image_view1);
iv.setImageBitmap(bm);

iv = (ImageView)findViewById(R.id.image_view2);
String b = getStringImage(bm);
decodeImage(iv, b);

你从Java编码和PHP编码获取不同的base64字符串的原因很简单。使用PHP时,你是直接将图像文件编码成base64格式;而使用Java时,则可能先将相同的图像文件进行解码成位图(Bitmap),然后再将该位图编码为JPEG流(这会产生一个与原始图片不同的JPEG图像),最终才将其编码为base64格式。
PHP: JPEG file -> base64

Java: JPEG file -> Bitmap -> JPEG stream (different from JPEG file) -> base 64

谢谢您。您的回答让我免于跳窗自杀。我已经花了数小时努力理解这个问题。感谢您,@Dalija Prasnikar。 - cfhpanteracfh
好的,我成功地将文件上传到服务器上了。我已经在Java中编写了HTTP实体部分,并在PHP中接收部分,一切都很顺利,但我一直得到非常小的文件,所以我尝试查看我的文件内容链接。你能帮我吗?如果我打扰你了,我很抱歉,但我真的需要帮助。@Dalija Prasnikar - cfhpanteracfh

1
这并不是直接回答问题,但我认为它仍然是正确的答案!对于此任务,绝对不需要使用Base64编码/解码。
图像和其他文件使用multipart/form-data编码上传到Web服务器。

内容类型"application/x-www-form-urlencoded"在发送大量二进制数据或包含非ASCII字符的文本时效率低下。应该使用内容类型"multipart/form-data"提交包含文件、非ASCII数据和二进制数据的表单。

好消息是您不需要自己进行编码。所有流行的HTTP客户端库都在内部处理它。您只需要告诉它们要上传哪些文件。这里有一个答案展示如何使用Volley完成它。这里有一个答案展示如何使用loopj异步HTTP客户端完成它。

看起来你在服务器端使用的是PHP。正如你非常清楚的知道,PHP内置了出色的支持来接受文件上传

不需要在任何一端进行Base64编码/解码。请注意,当你对二进制文件进行Base64编码时,它的大小会增加约30%,因此你的Base64编码的帖子将增加设备的内存,CPU和数据使用率。


好的。我想我看到了一个解决方案,只是当我看到这么多新东西时,很难理解它。我想给你的答案点赞,但不幸的是我还是一个Stack的新手。非常感谢你。如果我成功了,我会回复你的。 @e4c5 - cfhpanteracfh
好的,我成功地将文件上传到服务器上。我已经用Java编写了http实体部分,在PHP中接收部分,一切都运行良好,但是我一直得到非常小的文件,所以我尝试看一下我的文件内容 链接。你能帮我吗?这样寻求帮助是否违反了本网站的规则?如果是的话,对不起,我不会再打扰任何人了。:( @e4c5 - cfhpanteracfh
1
你的代码在 Q 中的第一眼看起来是在进行双重转换(从文件到位图,再从位图回到文件数据),但是你可以直接上传,只需要知道文件名即可(请参考我回答中提供的 Volley 示例)。 - e4c5
我这样做是因为服务器上的文件非常小,但名称和类型正确。所以我认为从位图转换为文件可能不好。因此,我想确定错误是否存在,但事实并非如此。@e4c5 - cfhpanteracfh
我已经更新了我的问题。谢谢你的回复。 :) @e4c5 - cfhpanteracfh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接