我想在我的Android应用程序中处理位图-该位图可能很大,因此我使用多线程来执行更快的 *** 作.这是我的代码(Runnable子代的一部分):
@OverrIDepublic voID run() { int imageHeight = filter.getBitmap().getHeight(); int start = threadNumber * imageHeight / threadCount; int stop = (threadNumber + 1) * imageHeight / threadCount; for (int j = start; j < stop; j++) { filter.processline(j); }}//...protected voID processline(int lineNumber){ int wIDth = bitmap.getWIDth(); int pixels[] = new int[wIDth]; bitmap.getPixels(pixels, 0, wIDth, 0, lineNumber, wIDth, 1); for (int i = 0; i < wIDth; i++) { pixels[i] = processpixel(pixels[i]); } bitmap.setPixels(pixels, 0, wIDth, 0, lineNumber, wIDth, 1);}
当我在池中仅使用1个线程时,一切工作正常.不幸的是,当我使用的线程号等于处理器的内核数(我的设备中为4个)时,结果如下所示(对于灰度滤镜):
有时看起来像:
> bitmap.getPixels(…)不起作用,因为输出中有黑线
> bitmap.setPixels(…)不起作用,因为输出中没有更改的行
我对吗?难道这些功能线程安全的?如何执行快速且线程安全的多线程位图过滤?
解决方法:
Skia库提供了AndroID中的2D图像处理功能,Chrome也使用了该功能.
很难找到一个明确的答案. “ Skia不是线程安全的,尽管[Bitmap使用的SkBitmap]是线程安全的……”我不知道该怎么想.我细读了一堆难以理解的JNI / C代码,这是我所能提供的最好的(似乎比其他任何人都可以做到):
我认为您应该在整个位图上调用bitmap.getPixels().然后将所得数组除以并进行处理.当所有线程完成后,重新组合结果并调用bitmap.setPixels()
看起来bitmap.getPixels()和bitmap.setPixels()应该只不过是memcpy(),但是在引用计数,图像缓存,色彩空间转换,预乘以及谁知道的背景下,还有很多事情要做还有什么.将Bitmap方法从并发处理中删除,可以避免麻烦.
总结以上是内存溢出为你收集整理的Java-Android位图多线程处理-不是线程安全的?全部内容,希望文章能够帮你解决Java-Android位图多线程处理-不是线程安全的?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)