加载较小版本的图像以提高Android性能

huangapple 未分类评论51阅读模式
英文:

Loading smaller version of an image for performance Android

问题

以下是翻译好的内容:

我有一张图片(1.84MB),想加载其较小版本以节省时间,同时也不想存储较小版本。这些文件位于可移动的SD卡中,我需要加载很多次,所以我想进行优化,因为目前加载时间太长了…

我阅读了加载大型位图文档。我以前使用Glide加载完整的图片。

经过一些测试,我得到了以下统计数据:
Glide加载(1.84MB):244,361,667 纳秒
位图加载(缩放1):370,811,511 纳秒
位图加载(缩放4):324,403,386 纳秒
位图加载(缩放8):269,223,073 纳秒
缩略图加载:245,250,729 纳秒

这意味着当加载一个8倍较小的图像时,使用位图加载时间略长,我不明白为什么。

以下是我的代码:

使用Glide加载:

private void loadGlide(Car c) {
    DocumentFile makerDir = contentDirectory.findFile(getMakerById(c.getMakerId()).getName());
    DocumentFile carPhoto = makerDir.findFile(c.getFilename());
    if(carPhoto == null) {
        Log.d("test", c.getFilename() + " 有问题");
    } else {
        Log.d("test", carPhoto.exists() + "");
    }
    ImageView img = new ImageView(this);
    img.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            goToEdit(c.getId());
        }
    });
    // 标准加载
    Glide.with(img.getContext()).load(carPhoto.getUri()).into(img);
    resultList.addView(img);
}

使用位图加载:

private void scaledLoad(Car c, int scale) {
    DocumentFile makerDir = contentDirectory.findFile(getMakerById(c.getMakerId()).getName());
    DocumentFile carPhoto = makerDir.findFile(c.getFilename());
    Bitmap b = null;
    // 解码图像大小
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = scale;
    // 将 DocumentFile 转换为 File
    File image = new File("image_path");
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(image);
        b = BitmapFactory.decodeStream(fis, null, options);
        fis.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    if(b != null) {
        ImageView img = new ImageView(this);
        img.setImageBitmap(b);
        resultList.addView(img);
    }
}

我还尝试了加载缩略图

private void loadThumbnail() {
    Bitmap ThumbImage = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile("filepath"),
            816, 612);
    ImageView img = new ImageView(this);
    img.setImageBitmap(ThumbImage);
    resultList.addView(img);
}

如果你有任何问题或者想要其他加载来自SD卡的缩小图像的快速方法,欢迎提问。提前感谢你。

英文:

I have an image (1.84MB) to load and I want to load a smaller version of it to gain time, I also don't want to store a smaller version of it. For info, these files are located in a removable SD card, and I need to load a lot, thats why I want to optimize it, as it takes too much time for the moment...

I red the load large bitmaps documentation. I previously used Glide to load the full image.

After some test, I get this statistics:
Glide load (1.84MB): 244'361'667 ns
Bitmap load (scale 1): 370'811'511 ns
Bitmap load (scale 4): 324'403'386 ns
Bitmap load (scale 8): 269'223'073 ns
Thumbnail load: 245'250'729 ns

Which means I get a slightly longer time with Bitmap while loading a 8 times smaller image, and I don't get why.

Here is my code:

load with glide:

private void loadGlide(Car c) {
DocumentFile makerDir = contentDirectory.findFile(getMakerById(c.getMakerId()).getName());
DocumentFile carPhoto = makerDir.findFile(c.getFilename());
if(carPhoto == null) {
    Log.d("test", c.getFilename() + " problem");
} else {
    Log.d("test", carPhoto.exists() + "");
}
ImageView img = new ImageView(this);
img.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        goToEdit(c.getId());
    }
});
// standard loading
Glide.with(img.getContext()).load(carPhoto.getUri()).into(img);
resultList.addView(img);

}

load with bitmap:

private void scaledLoad(Car c, int scale) {
DocumentFile makerDir = contentDirectory.findFile(getMakerById(c.getMakerId()).getName());
DocumentFile carPhoto = makerDir.findFile(c.getFilename());
Bitmap b = null;
//Decode image size
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = scale;
// convert DocumentFile to File
File image = new File("image_path");
FileInputStream fis = null;
try {
    fis = new FileInputStream(image);
    b = BitmapFactory.decodeStream(fis, null, options);
    fis.close();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
if(b != null) {
    ImageView img = new ImageView(this);
    img.setImageBitmap(b);
    resultList.addView(img);
}

}

I also tried to load thumbnails:

private void loadThumbnail() {
Bitmap ThumbImage = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile("filepath"),
        816, 612);
ImageView img = new ImageView(this);
img.setImageBitmap(ThumbImage);
resultList.addView(img);

}

And here is the test code if you want:

long t0 = System.nanoTime();
scaledLoad(c, 1);
// or
loadGlide(c);
long t1 = System.nanoTime();
t1 = (t1-t0);
Log.d("test", "t1:" + t1);

If you can answer me or give me any other alternative to load underscaled images from SD card FAST, you are welcome. Thanks in advance.

答案1

得分: 0

如果您正在使用Glide,您可以使用函数"override(width, height)"将调整大小的图像加载到imageView中。

这篇博客解释了如何做到这一点:https://futurestud.io/tutorials/glide-image-resizing-scaling#imageresizingwithoverridexy

英文:

If you are using Glide you can use the function "override(width,height)" to load resized image into the imageView.

This blogs explains how to do it : https://futurestud.io/tutorials/glide-image-resizing-scaling#imageresizingwithoverridexy

huangapple
  • 本文由 发表于 2020年5月5日 06:25:16
  • 转载请务必保留本文链接:https://java.coder-hub.com/61602646.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定