gpt4 book ai didi

android - 位图创建和绘制速度慢...快

转载 作者:行者123 更新时间:2023-11-29 02:32:29 27 4
gpt4 key购买 nike

这在一小部分是一个问题(因为我不明白为什么它会有所不同),在很大程度上是一篇希望能帮助其他一些可怜的程序员的帖子。

我有一个代码库,是我大约 5-7 年前第一次开始 Android 编程时编写的,它具有将文件读入内存(用于很多事情)的功能,以及加载功能来自 .png 文件的位图。后一个函数使用“读取文件”函数将文件中的字节读入字节数组,然后从中创建位图。我知道这不是真正干净的代码,也可能不是最好的方法,但它有效,为什么要搞砸一些有效的东西?

除了... Android(尤其是 Oreo)的最后几个版本导致我的应用程序中的绘图(来自位图)真的变慢了 WAYYYYYY。我挣扎了好几天,试图弄清楚发生了什么,最后偶然发现了一个修复程序……我不明白。

这是“将 .png 文件加载到位图中”功能的核心(原样)。请注意,整个“if-for-for”透明度内容可能会被完全忽略,这是将一种或两种颜色的像素转换为透明像素的特殊情况。在此 block 的入口处,.png 文件已被读入“位”。

BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inPreferredConfig = Bitmap.Config.valueOf("ARGB_8888");
Bitmap imbm = BitmapFactory.decodeByteArray(bits, 0, flen, bfo);// this makes an IMmutable bitmap
bits = null;
System.gc();
Bitmap bm = imbm.copy(Bitmap.Config.valueOf("ARGB_8888"), true);// convert it to a MUTABLE bitmap
imbm.recycle();
imbm = null;
w = bm.getWidth();
h = bm.getHeight();
// do transparency stuff
if (transX1 >= 0 && transX1 < w && transY1 >= 0 && transY1 < h) {
clr1 = bm.getPixel(transX1, transY1);
clr2 = bm.getPixel(transX2, transY2);
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
clr = bm.getPixel(x, y);
// convert any 0x00818181 (middle-gray) pixels to 0x00808080
// so that 0x00818181 is guaranteed to never be used in customer-created bitmaps
if (clr1 != 0xFF818181 && clr == 0xFF818181) bm.setPixel(x, y, 0xFF808080);
else if (clr == clr1 || clr == clr2) bm.setPixel(x, y, clr & 0x00000000);
}
}
}
System.gc(); // request garbage-collection to try to avoid out-of-memory when loading/creating bitmap
return bm;

返回的位图随后被用作使用 dC.drawBitmap(bm, sRect, dRect, kPaint) 将点点滴滴绘制到上下文中的源。但是,Android 的变化导致速度减慢。修复结果是用这段代码替换上面最后的“return bm”:

Bitmap tBM = Bitmap.createBitmap(w, h, Bitmap.Config.valueOf("ARGB_8888"));
Rect sRect = new Rect();
Rect dRect = new Rect();
sRect.set(0, 0, w, h);
dRect.set(0, 0, w, h);
Canvas dC = new Canvas(tBM);
dC.drawBitmap(bm, sRect, dRect, kPaint);
dC = null;
bm = null;
return tBM;

换句话说,它只是采用先前版本生成的“bm”位图,创建另一个相同大小的位图,将“bm”绘制到新位图中,然后返回新位图而不是先前版本。

关于以前构建位图的方法似乎使它处于“错误的形式”,这使得从中绘制非常慢,同时对它执行 createBitmap() 和 drawBitmap() 会生成一个位图,您可以绘制速度非常快。

知道为什么会这样吗? (是的,我尝试了所有常见的 RGB_565 东西,等等)这很有效。但是,如果我了解为什么会发生这种情况,那就太好了,就像我说的那样,我的努力可能对将来的某些人有用。

最佳答案

我的怀疑是正确的,减速是由 decodeByteArray()(某种程度上)引起的。

首先,随着更多的研究(以及高龄和知识),我意识到通过设置 BitmapFactory.Options.inMutable=true 可以更容易地解决不可变/可变问题。

但是,问题的真正解决方案是将代码的“核心”更改为:

BitmapFactory.Options   bfo = new BitmapFactory.Options();
bfo.inPreferredConfig = Bitmap.Config.valueOf("ARGB_8888");
bfo.inMutable = true; // this makes an mutable bitmap
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
bfo.inPreferredColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
}
Bitmap bm = BitmapFactory.decodeByteArray(bits, 0, flen, bfo);
bits = null;

换句话说,我摆脱了上面提到的不可变/可变位图副本,然后我测试在 Oreo 或更高版本上运行,如果是,则设置 inPreferredColorSpace 成员。这是在 Oreo (API 26) 中添加的。当他们添加类似的东西时,我会认为它会被设置为一个合理的默认值,我想它是,但显然不能很好地将位图绘制到显示器上。默认值为“null”,但将其更改为 SRGB 足以使我从生成的位图闪电般快速地绘制到显示器上,所以我假设(总是危险的)这个色彩空间问题是由 kludge 解决的我在原始帖子中所做的位图的副本。

关于android - 位图创建和绘制速度慢...快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48835147/

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