在显示的位图上调用setPixel时出错

时间:2014-10-12 01:23:24

标签: android multithreading bitmap imageview

我正在开发简单的应用程序,它应该对用户进行一些图像处理和显示进度。因为我希望用户看到整个过程,所以在过程完成后无法将位图设置为imageView,或者在UI线程中完成工作。

我最终得到了以下解决方案:

  1. 从源
  2. 获取位图
  3. 将位图设置为ImageView
  4. 在后台线程上运行图像处理任务(使用AsyncTask
  5. 以下是简化的源代码:

    public class ImageProcessingTask extends AsyncTask<Params, Void, Bitmap>
    {
        private Listener listener = null;
    
        public ImageProcessingTask(Listener listener)
        {
            this.listener = listener;
        }
    
        @Override
        protected Bitmap doInBackground(Params... params)
        {
            // Do work, call setPixel in cycle without Thread.sleep() is enough
            ImageProcessing.processImage(params[0]);
        }
    
        @Override
        protected void onPostExecute(Bitmap bitmap)
        {
            if(listener != null)
            {
                listener.onImageProcessingTaskPostExecute(bitmap);
            }
        }
    }
    

    一切都很好,除了偶尔大约一半的图像(随机),过程停止,我得到这个

    E/OpenGLRenderer﹕ Cannot generate texture from bitmap

    在这个thread中,我发现它与硬件加速有关,所以我将其关闭

    imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    

    问题从控制台中消失了,但我实现的每一个都是位图在完全相同的位置上从ImageView中消失,而不是冻结。

    我在互联网上找到了几个讨论,但我还没有找到解决这个问题的有用方法。我尝试使用synchronized语句和java.util.concurrent.Semaphore同步访问位图,但没有成功。

    最后一个有趣的事实我注意到 - 我有简单的颜色检测算法,计算图片上各个颜色的数量。如果我在图像处理功能之后运行它,它会返回不同的值,就好像位图根本没有改变颜色(物理上,所以它可能不仅仅是OpenGL问题)。

    我使用的方法列表:

    • 禁用ImageView的硬件加速(参见上文)
    • 同步访问位图(无更改)
    • setPixels而不是setPixel(无更改)
    • copyPixelsFromBuffer + copyPixelsToBuffer而不是setPixel(无变化)
    • 使用Handler(无更改)
    • 在UI线程中移动setPixel
    • 更多......

0 个答案:

没有答案