【问题标题】:Android Bitmap multithreaded processing - not thread-safe?Android位图多线程处理 - 不是线程安全的?
【发布时间】:2015-06-29 12:33:28
【问题描述】:

我想在我的 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)时,结果如下(用于灰度过滤器):

有时看起来像:

  • bitmap.getPixels(...) 不起作用,因为输出中有黑线
  • bitmap.setPixels(...) 不起作用,因为输出中有未更改的行

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

【问题讨论】:

    标签: java android multithreading image-processing thread-safety


    【解决方案1】:

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

    很难找到明确的答案。 “Skia 不是线程安全的,尽管 SkBitmap [Bitmap 使用] 线程安全的......”我不知道该怎么想。我仔细阅读了一堆难以理解的 JNI/C++ 代码,这是我能提供的最好的(这似乎比其他任何人都做得更多):

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

    看起来bitmap.getPixels()bitmap.setPixels() 应该只不过是memcpy()s,但是在引擎盖下还有很多事情要做,包括引用计数、图像缓存、色彩空间转换、预乘以及谁知道什么别的。将Bitmap 方法从并发处理中移除应该可以让您远离麻烦。

    【讨论】:

    • 这是我的最终答案。 ) 删除我之前的。
    • 我已经用bitmap.getPixels() 尝试过您的解决方案,但它也无法正常工作 - 存在未处理图像的片段。不幸的是,我用这个恢复了更改。也许稍后我会再次编写这段代码并显示输出。
    • 当你这样做时,请发布执行线程的代码。干杯
    • 抱歉,使用getPixels 解决整个图像效果很好,显然我第一次犯了错误。这种方法的一个缺点是内存消耗大。在没有任何副本的情况下“就地”进行过滤是完美的,但使用“getPixel”和“setPixel”显然是个坏主意,而且它们非常慢。除了使用Android NDK,还有没有更好的解决方案?
    • 我认为 NDK 可能是要走的路。您可以寻找第三方 2D 图像处理库,但您仍然必须将像素复制到位图中,以便用户可以看到图像。叹息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多