设置选项时 BitmapFactory.decodeStream 返回 null
我在使用 BitmapFactory.decodeStream(inputStream)
时遇到问题。当不带选项使用它时,它将返回一个图像。但是当我将它与 .decodeStream(inputStream, null, options)
中的选项一起使用时,它永远不会返回位图。
我想做的是在实际加载位图之前对其进行下采样以节省内存。 我读过一些很好的指南,但没有使用 .decodeStream
。
工作正常
URL url = new URL(sUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is, null, options);
不工作
InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is, null, options);
InputStream is = connection.getInputStream();
Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
Boolean scaleByHeight = Math.abs(options.outHeight - TARGET_HEIGHT) >= Math.abs(options.outWidth - TARGET_WIDTH);
if (options.outHeight * options.outWidth * 2 >= 200*100*2){
// Load, scaling to smallest power of 2 that'll get it <= desired dimensions
double sampleSize = scaleByHeight
? options.outHeight / TARGET_HEIGHT
: options.outWidth / TARGET_WIDTH;
options.inSampleSize =
(int)Math.pow(2d, Math.floor(
Math.log(sampleSize)/Math.log(2d)));
}
// Do the actual decoding
options.inJustDecodeBounds = false;
Bitmap img = BitmapFactory.decodeStream(is, null, options);
I'm having issues with BitmapFactory.decodeStream(inputStream)
. When using it without options, it will return an image. But when I use it with options as in .decodeStream(inputStream, null, options)
it never returns Bitmaps.
What I'm trying to do is to downsample a Bitmap before I actually load it to save memory.
I've read some good guides, but none using .decodeStream
.
WORKS JUST FINE
URL url = new URL(sUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is, null, options);
DOESN'T WORK
InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is, null, options);
InputStream is = connection.getInputStream();
Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
Boolean scaleByHeight = Math.abs(options.outHeight - TARGET_HEIGHT) >= Math.abs(options.outWidth - TARGET_WIDTH);
if (options.outHeight * options.outWidth * 2 >= 200*100*2){
// Load, scaling to smallest power of 2 that'll get it <= desired dimensions
double sampleSize = scaleByHeight
? options.outHeight / TARGET_HEIGHT
: options.outWidth / TARGET_WIDTH;
options.inSampleSize =
(int)Math.pow(2d, Math.floor(
Math.log(sampleSize)/Math.log(2d)));
}
// Do the actual decoding
options.inJustDecodeBounds = false;
Bitmap img = BitmapFactory.decodeStream(is, null, options);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题是,一旦您使用 HttpUrlConnection 中的 InputStream 来获取图像元数据,您就无法倒回并再次使用相同的 InputStream。
因此,您必须创建一个新的输入流来进行图像的实际采样。
The problem was that once you've used an InputStream from a HttpUrlConnection to fetch image metadata, you can't rewind and use the same InputStream again.
Therefore you have to create a new InputStream for the actual sampling of the image.
尝试用 BufferedInputStream 包装 InputStream。
Try wrap InputStream with BufferedInputStream.
我认为问题在于“计算比例因子”逻辑,因为其余代码对我来说看起来是正确的(当然假设输入流不为空)。
如果您可以将此例程中的所有大小计算逻辑分解为一个方法(将其称为calculateScaleFactor() 或其他)并首先独立测试该方法,那就更好了。
像这样:
并独立测试 getScaleFactor(...) 。
如果尚未完成,它也将有助于用 try..catch{} 块包围整个代码。
I think the problem is with the "calculate-scale-factor" logic because rest of the code looks correct to me (assuming of course that inputstream is not null).
It would be better if you can factor out all the size calculation logic from this routine into a method(call it calculateScaleFactor() or whatever) and test that method independently first.
Something like:
and test getScaleFactor(...) independently.
It will also help to surround the entire code with try..catch{} block, if not done already.
您可以将InputStream转换为字节数组,并使用decodeByteArray()。例如,
You can convert the InputStream to a byte array, and use the decodeByteArray(). For example,