Android 位图多线程处理 - 不是线程安全的?

Android Bitmap multithreaded processing - not thread-safe?

我想在我的 Android 应用程序中处理位图 - 位图可能很大,所以我使用多线程来执行更快的操作。这是我的代码(Runnable child 的一部分):

@Override
public 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 个)时,结果如下(对于灰度过滤器):

有时看起来像:

我说的对吗?这些函数是线程不安全的吗?我应该如何执行多线程位图过滤才能快速且线程安全?

Android 中的 2D 图像处理由 Skia 库提供,Chrome 也使用。

很难找到明确的答案。 "Skia is not thread-safe, although SkBitmap [used by Bitmap] is thread-safe..." 不知道怎么想的。我仔细阅读了一堆难以理解的 JNI/C++ 代码,这是我能提供的最好的代码(这似乎比其他任何人都多):

我认为你应该在 整个位图 上调用 bitmap.getPixels()。然后划分结果数组并线程化处理。当所有线程完成后,重新assemble结果并调用bitmap.setPixels()

看起来 bitmap.getPixels()bitmap.setPixels() 应该只不过是 memcpy()s,但在引用计数、图像缓存、颜色等方面还有很多事情要做space 转换、预乘以及谁知道还有什么。将 Bitmap 方法从并发处理中取出应该可以让您远离麻烦。