在android中解码流时保留图像质量

在android中解码流时保留图像质量,第1张

概述我在SD卡上有一个图像,需要在图像视图上显示 问题是,在解码之后,质量似乎恶化了.有没有什么方法可以保持质量,同时保留记忆? 或者,如果我使用更大的图像,是否有任何方法可以保留内存(避免加载太大的位图)和缩放? (我需要保持原始图像的大小) 谢谢你的帮助. public Bitmap decodeFile(String pubKey, int bookPageID, int type) 我在SD卡上有一个图像,需要在图像视图上显示

问题是,在解码之后,质量似乎恶化了.有没有什么方法可以保持质量,同时保留记忆?

或者,如果我使用更大的图像,是否有任何方法可以保留内存(避免加载太大的位图)和缩放? (我需要保持原始图像的大小)

谢谢你的帮助.

public Bitmap decodefile(String pubKey,int bookPageID,int type)        throws IOException {    Bitmap b = null;    file f = null;    String uri = null;    fileinputStream fis = null;    Log.d(TAG,"pageID to read: " + bookPageID);    IRIssue issue = broker.model.issueDataStore.getIRIssue(pubKey);    String imageFolder = IRConstant.issueFolder(issue.year,issue.month,issue.day,issue.pubKey);    // pageID - 1 since the page is an array (start at 0),but page ID start at 1    if (type == 2){        uri = imageFolder + issue.vol[0].pages[bookPageID - 1].graphicUri;    }else {        uri = imageFolder + issue.vol[0].pages[bookPageID - 1].textUri;    }    f = new file(uri);    Log.d(TAG,"is file: " + uri + " exist?" + f.exists());    BitmapFactory.Options options = new BitmapFactory.Options();    options.inPurgeable = true;    options.ininputShareable = true;    options.inJustDecodeBounds = false;    options.inPreferredConfig = Bitmap.Config.ARGB_8888;    fis = new fileinputStream(f);    b = BitmapFactory.decodeStream(fis,null,options);    fis.close();    return b;}
解决方法 以下代码使用 Displaying Bitmaps Efficiently中的几个概念
首先关闭位图读取是在后台线程中完成的,我在inputStream上使用mark / reset(用Bufferedinputstream包装),当我们试图找出计算尺度时要使用的图像大小时,不要从流中读取更多内容因子.下面的示例代码对图像进行子采样,以匹配320×240像素的大小.在非示例代码中,可以使用简单的回调接口将位图从onPostExecute发送到实现类(回调接口实现器).或者直接将视图作为AsyncTask的成员提供,并在onPostExecute中设置位图.

使用(我的设备上的示例下载图像)调用代码:

BitmapTask task = new BitmapTask(getContentResolver());task.execute(Uri.parse("file:///storage/emulated/0/Download/download.jpg"));

有问题的课程

private static class BitmapTask extends AsyncTask<Uri,VoID,Bitmap> {    // prevent mem leaks    private WeakReference<ContentResolver> mWeakContentResolver;    public BitmapTask(ContentResolver resolver) {        mWeakContentResolver = new WeakReference<ContentResolver>(resolver);    }    @OverrIDe    protected Bitmap doInBackground(Uri... params) {        Bitmap bitmap = null;        ContentResolver resolver = mWeakContentResolver.get();        if (resolver != null) {            BufferedinputStream stream = null;            try {                stream = new BufferedinputStream(                        resolver.openinputStream(params[0]));                stream.mark(1 * 1024);                BitmapFactory.Options options = new BitmapFactory.Options();                options.inJustDecodeBounds = true;                // Find out size of image                BitmapFactory.decodeStream(stream,options);                try {                    stream.reset();                } catch (IOException e) {                    Log.d(TAG,"reset Failed");                }                int imageHeight = options.outHeight;                int imageWIDth = options.outWIDth;                String imageType = options.outMimeType;                Log.d(TAG,"w,h,mime " + imageWIDth + "," + imageHeight                        + "," + imageType);                options.inJustDecodeBounds = false;                // Calculate down scale factor                options.inSampleSize = calculateInSampleSize(options,320,240);                return BitmapFactory.decodeStream(stream,options);            } catch (fileNotFoundException e) {                bitmap = null;            } finally {                IoUtils.closeStreamSilently(stream);            }        }        return bitmap;    }    @OverrIDe    protected voID onPostExecute(Bitmap result) {        Log.d(TAG,"bitmap result: "                        + ((result != null) ? "" + result.getByteCount()                                : "0"));        result.recycle();    }}public static int calculateInSampleSize(BitmapFactory.Options options,int reqWIDth,int reqHeight) {    // Raw height and wIDth of image    final int height = options.outHeight;    final int wIDth = options.outWIDth;    int inSampleSize = 1;    if (height > reqHeight || wIDth > reqWIDth) {        final int halfheight = height / 2;        final int halfWIDth = wIDth / 2;        // Calculate the largest inSampleSize value that is a power of 2 and        // keeps both        // height and wIDth larger than the requested height and wIDth.        while ((halfheight / inSampleSize) > reqHeight                && (halfWIDth / inSampleSize) > reqWIDth) {            inSampleSize *= 2;        }    }    return inSampleSize;}

编辑:对于大型输入流可能存在标记/重置技术的问题,Skimagedecoder :: Factory返回null有时可以在日志中看到,导致空位图,关于此问题的其他SO问题:SkImageDecoder::Factory returned null.它可以通过以下方式修复:再次重新启动流变量stream = new resolver.openinputStream(params [0]));在doInBackground中返回之前

编辑2:如果你必须保留图像大小但不想限制内存使用,你可以使用options.inPreferredConfig = Bitmap.Config.RGB_565;将每个像素的内存减半,但要记住图像可能不再具有高质量(实验!).

总结

以上是内存溢出为你收集整理的在android中解码流时保留图像质量全部内容,希望文章能够帮你解决在android中解码流时保留图像质量所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1122164.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-29
下一篇2022-05-29

发表评论

登录后才能评论

评论列表(0条)

    保存