gpt4 book ai didi

android - 从二进制 base64 加载图像

转载 作者:太空狗 更新时间:2023-10-29 14:02:10 27 4
gpt4 key购买 nike

编辑:这是 Android 版本 <4.3 Kitkat 中的错误。它与 Android 中的 libjpeg 库有关,它无法处理缺少 EOF/EOI 位的 JPEG,或者显然它不喜欢的元数据/EXIF 数据。 https://code.google.com/p/android/issues/detail?id=9064

原始问题:

我在我的应用中加载图片时遇到问题。

我的端点发送包含 BASE64 编码图像的 JSON。根据 REST 调用,这些图像可以是 PNGJPG。某些 JPG 文件存在结尾缺少 EOF 位的问题。 PNG 文件可以工作,一些 JPG 文件可以工作,但不幸的是,Oracle DB 中存在很多有问题的 JPG 文件(存储为 BLOB)。我无法控制数据库。

我一直在这里查看 Google 错误: https://code.google.com/p/android/issues/detail?id=9064和这里: https://code.google.com/p/android/issues/detail?id=57502

使用自定义 ICC 配置文件的编码为 CYMK 时也会出现此问题。

以标准方式解码图像返回false:

byte[] imageAsBytes = Base64.decode(base64ImageString, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length);

根据上面的错误报告,Android 中内置的 JPG 解析器是罪魁祸首。

我正在尝试为我的设备找出解决方法,该设备卡在 4.2.2 上。对于此操作系统版本,我别无选择。

我认为尝试使用像 Universal Image Loader 这样的图像加载器库可能是个好主意,但这需要我将图像存储在本地或存储在 URL 上。当我从 REST 服务器获取 BASE64 中的数据时,我无法使用它。一个选项是在扩展 BaseImageDecoder 的自定义类中支持 decodeByteArray,如底部的开发人员所述:https://github.com/nostra13/Android-Universal-Image-Loader/issues/209

这就是我卡住的地方。我已经有一个自定义图像解码器来尝试处理 JPG 文件中缺少 EOF 标记的问题,但我不知道如何编辑它以添加对 decodeByteArray 的支持>.

这是我的CustomImageDecoder:

public class CustomImageDecoder extends BaseImageDecoder {

public CustomImageDecoder(boolean loggingEnabled) {
super(loggingEnabled);
}

@Override
protected InputStream getImageStream(ImageDecodingInfo decodingInfo) throws IOException {
InputStream stream = decodingInfo.getDownloader()
.getStream(decodingInfo.getImageUri(), decodingInfo.getExtraForDownloader());
return stream == null ? null : new JpegClosedInputStream(stream);
}

private class JpegClosedInputStream extends InputStream {

private static final int JPEG_EOI_1 = 0xFF;
private static final int JPEG_EOI_2 = 0xD9;
private final InputStream inputStream;
private int bytesPastEnd;

private JpegClosedInputStream(final InputStream iInputStream) {
inputStream = iInputStream;
bytesPastEnd = 0;
}

@Override
public int read() throws IOException {
int buffer = inputStream.read();
if (buffer == -1) {
if (bytesPastEnd > 0) {
buffer = JPEG_EOI_2;
} else {
++bytesPastEnd;
buffer = JPEG_EOI_1;
}
}

return buffer;
}
}
}

顺便说一下,使用上面的自定义类,我正在尝试像这样加载我的字节数组:

byte[] bytes = Base64.decode(formattedB64String, Base64.NO_WRAP);
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
String imageId = "stream://" + is.hashCode();
...
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.displayImage(imageId, userImage, options);

我得到这个错误:ImageLoader: 图片无法解码 [stream://1097215584_656x383]

通用图像加载器不允许 stream:// 模式,所以我创建了一个允许它的自定义 BaseImageDownloader 类:

public class StreamImageDownloader extends BaseImageDownloader {

private static final String SCHEME_STREAM = "stream";
private static final String STREAM_URI_PREFIX = SCHEME_STREAM + "://";

public StreamImageDownloader(Context context) {
super(context);
}

@Override
protected InputStream getStreamFromOtherSource(String imageUri, Object extra) throws IOException {
if (imageUri.startsWith(STREAM_URI_PREFIX)) {
return (InputStream) extra;
} else {
return super.getStreamFromOtherSource(imageUri, extra);
}
}
}

因此,如果有人可以帮助我创建一个更好的 CustomImageDecoder 来处理 BASE64 编码的字符串,或者包含图像的 byte[]我可以使用decodeByteArray,我将不胜感激!

谢谢。

最佳答案

UnversalImageLoader 使用以下方案来解码文件

"h t t p ://site.com/image.png" // from Web
"file:///mnt/sdcard/image.png" // from SD card
"file:///mnt/sdcard/video.mp4" // from SD card (video thumbnail)
"content://media/external/images/media/13" // from content provider
"content://media/external/video/media/13" // from content provider (video thumbnail)
"assets://image.png" // from assets
"drawable://" + R.drawable.img // from drawables (non-9patch images)

你的方案是stream://

希望对您有所帮助。

关于android - 从二进制 base64 加载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34767678/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com