Android:BitmapFactory.decodeByteArray提供像素化位图
image-processing
5
0

我正在使用一个Android应用程序,该应用程序显示从Flickr下载的照片。我从字节数组中获得一个位图对象,该对象又从相关的Flickr URL中读取,如下所示:

BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inDither = true;
opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opt);

然后,在View对象的onDraw方法中将位图绘制到画布上:

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(bitmap, 0, 0, paint); 

问题是生成的图片被像素化,我不知道为什么。我尝试了很多opt和paint对象的变体,但是没有运气。我的应用程序中显示的图片与原始URL上的图片之间的区别大致由以下内容证明:

图片质量不佳,请参见左上角的像素化http://homepages.inf.ed.ac.uk/s0677975/bad.jpg

好图片,这是预期的结果http://homepages.inf.ed.ac.uk/s0677975/good.jpg

例如,查看左上角的云,以查看区别。

请注意,从项目资源加载并以类似方式绘制的JPEG图片显示得很好,即没有像素。

有人能给我提示为什么会这样吗?

详细说来,字节数组是从Flickr获得的,方法如下:这基于Romain Guy的Photostream应用程序中的代码:

InputStream in = new BufferedInputStream(url.openStream(), IO_BUFFER_SIZE);
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
copy(in, out);
out.flush();
final byte[] data = dataStream.toByteArray();

PS:我还在android.developer Google论坛上发布了这个问题的变体。


非常感谢您的建议-现在我真的很困惑!我按照您的建议做了,发现直接由下载的字节数组产生的图像确实是像素化的。但是,这是从完全相同的URL下载的,在我的计算机上访问该URL时,该URL没有像素化。这是相应的Flickr URL:

http://farm3.static.flickr.com/2678/4315351421_54e8cdb8e5.jpg

更奇怪的是,当我在模拟器中而不是在手机(HTC Hero)上运行相同的应用程序时,没有像素化。

这到底怎么可能?

以下是我用于从URL加载位图的代码-它基于Romain Guy的Photostream应用,并且结合了Will的建议将原始字节数组写入文件:

Bitmap loadPhotoBitmap(URL url) {
    Bitmap bitmap = null;
        InputStream in = null;
        BufferedOutputStream out = null;

        try {

            FileOutputStream fos = new FileOutputStream("/sdcard/photo-tmp.jpg");
            BufferedOutputStream bfs = new BufferedOutputStream(fos);

            in = new BufferedInputStream(url.openStream(),
                    IO_BUFFER_SIZE);

            final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
            out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
            copy(in, out);                    
            out.flush();
            final byte[] data = dataStream.toByteArray();

            bfs.write(data, 0, data.length);
            bfs.flush();

            BitmapFactory.Options opt = new BitmapFactory.Options();
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opt);

        } catch (IOException e) {
            android.util.Log.e(LOG_TAG, "Could not load photo: " + this, e);
        } finally {
            closeStream(in);
            closeStream(out)
            closeStream(bfs);
        }

        return bitmap;
    }

private static void copy(InputStream in, OutputStream out) throws IOException {
    byte[] b = new byte[IO_BUFFER_SIZE];
    int read;
    while ((read = in.read(b)) != -1) {
        out.write(b, 0, read);
    }
}

private static void closeStream(Closeable stream) {
    if (stream != null) {
        try {
            stream.close();
        } catch (IOException e) {
            android.util.Log.e(LOG_TAG, "Could not close stream", e);
        }
    }
}

我要疯了吗?最好,迈克尔。

参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

好的,我终于明白了:我的移动网络似乎在进行图像压缩以节省带宽。

因此,从我的手机下载的图片质量比从我的计算机下载的图片低。

这对于我的应用程序来说实在太可惜了,但是我不认为我可以做任何事情。叹。

再次感谢您的输入!

最好,迈克尔。

收藏
评论

将从URL提取的原始字节写入/sdcard/tmp.jpg ,然后在您的PC上查看。

JPEG图像以8x8(或16x16)图块压缩。您所描述的“像素化”实际上位于这些图块中,这表明“不良”图像是比其他图像更具压缩性的JPEG。

因此,我预计实际的问题是正在下载的图像是质量很低的版本,例如,打算用于缩略图/预览用例的版本。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号