【问题标题】:Draw Bitmap in AsyncTask在 AsyncTask 中绘制位图
【发布时间】:2015-07-27 06:15:31
【问题描述】:
public class MainActivity extends ActionBarActivity implements OnClickListener {

    private ImageButton btnDefault, btnGamma, btnContrast, btnSharpen, btnOpacity, btnCloseEffect;
    private TextView txtEffect, txtSeekBarValue;
    private Toolbar toolbarEffects, toolbarEffectDetails, toolbarEffectsFooter, toolbarSeekbar;
    private SeekBar seekBar;

    private static int gammaVal, contrastVal, sharpenVal, opacityVal; 
    private static String activeEffect;


    private Button btnLocalFile;
    public ImageView imgPreview;
    public Bitmap bm;
    public Canvas canvas;
    public Paint paint;
    public Bitmap.Config conf;
    private static URI uri;

    /**
     * NEW
     */
    private ImageButton btnFileOpen;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        Toolbar topToolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
        topToolbar.bringToFront();
        /**
         * NEW
         */
        btnFileOpen = (ImageButton) findViewById(R.id.btn_fileOpen);

        imgPreview = (ImageView) super.findViewById(R.id.imgPreview);

        /** Efekt değişkenlerinin default değerleri */
        activeEffect = "";
        gammaVal = 50; // 1.0
        contrastVal = 100; // 100 = 0
        sharpenVal = 0;
        opacityVal = 100;

        /** Efekt Tanımlamaları */
        btnDefault = (ImageButton) findViewById(R.id.btn_default);
        btnGamma = (ImageButton) findViewById(R.id.btn_gamma);
        btnContrast = (ImageButton) findViewById(R.id.btn_contrast);
        btnSharpen = (ImageButton) findViewById(R.id.btn_sharpen);
        btnOpacity = (ImageButton) findViewById(R.id.btn_opacity);
        btnCloseEffect = (ImageButton) findViewById(R.id.btn_closeEffect);

        /** Efekt Click Atamaları */
        btnDefault.setOnClickListener(this);
        btnGamma.setOnClickListener(this);
        btnContrast.setOnClickListener(this);
        btnSharpen.setOnClickListener(this);
        btnOpacity.setOnClickListener(this);
        btnCloseEffect.setOnClickListener(this);


        toolbarEffects = (Toolbar) findViewById(R.id.toolbar_effects);
        toolbarEffectsFooter = (Toolbar) findViewById(R.id.toolbar_effects_footer);
        toolbarEffectDetails = (Toolbar) findViewById(R.id.toolbar_effect_details);
        toolbarSeekbar = (Toolbar) findViewById(R.id.toolbar_seekbar);
        txtEffect = (TextView) findViewById(R.id.txt_effect);

        /** SeekBar */
        seekBar = (SeekBar) findViewById(R.id.seekBar);
        txtSeekBarValue = (TextView) findViewById(R.id.seekBar_Value);

        seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                /*
                 * SeekBar' dan elini çektiği anda (durduğunda)
                 * birşey yaptırmak için buraya yazmak gerekiyor.
                 */
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                /*
                 * SeekBar' a basıldığı anda birşey yaptırmak için
                 * buraya yazmak gerekiyor. 
                */
            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                String progressText = null;

                if (fromUser) {
                    if (activeEffect.equals("contrast")) {
                        contrastVal = progress;
                        progressText = String.valueOf(contrastVal - 100);
                    } else if (activeEffect.equals("gamma")) {
                        gammaVal = progress;
                        progressText = String.valueOf(gammaVal);
                    } else if (activeEffect.equals("opacity")) {
                        opacityVal = progress;
                        progressText = opacityVal + "%";
                    } else if (activeEffect.equals("sharpen")) {
                        sharpenVal = progress;
                        progressText = sharpenVal + "%";
                    }
                } else {
                    if (activeEffect.equals("contrast")) {
                        progressText = String.valueOf(contrastVal - 100);
                    } else if (activeEffect.equals("gamma")) {
                        progressText = String.valueOf(gammaVal);
                    } else if (activeEffect.equals("opacity")) {
                        progressText = opacityVal + "%";
                    } else if (activeEffect.equals("sharpen")) {
                        progressText = sharpenVal + "%";
                    }
                }
                txtSeekBarValue.setText(progressText);
            }
        });

        try {
            uri = new URI("jpip://192.168.1.71:3312/CB.jp2");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * NEW
     */

    public void btn_fileOpen_Click(View view) {
        new Painter().execute();
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        int id = v.getId();

        switch (id) {
        case R.id.btn_default:
            gammaVal = 50; // 1.0
            contrastVal = 100; // 100 = 0
            sharpenVal = 0;
            opacityVal = 100;
            break;          
        case R.id.btn_gamma:
            activeEffect = "gamma";
            seekBar.setMax(100);
            seekBar.setProgress(gammaVal);
            chooseEffect("GAMMA");
            break;
        case R.id.btn_contrast:
            activeEffect = "contrast";
            seekBar.setMax(200);
            seekBar.setProgress(contrastVal);
            txtSeekBarValue.setText(String.valueOf(contrastVal - 100));
            chooseEffect("CONTRAST");
            break;
        case R.id.btn_sharpen:
            activeEffect = "sharpen";
            seekBar.setMax(100);
            seekBar.setProgress(sharpenVal);
            chooseEffect("SHARPEN");
            break;
        case R.id.btn_opacity:
            activeEffect = "opacity";
            seekBar.setMax(100);
            seekBar.setProgress(opacityVal);
            chooseEffect("OPACITY");
            break;      
        case R.id.btn_closeEffect:
            closeEffect();
            break;
        default:
            break;
        }

    }

    public void chooseEffect(String effect) {
        txtEffect.setText(effect);
        toolbarEffects.setVisibility(View.GONE);
        toolbarEffectsFooter.setVisibility(View.GONE);
        toolbarEffectDetails.setVisibility(View.VISIBLE);
        toolbarSeekbar.setVisibility(View.VISIBLE);
    }

    public void closeEffect() {
        toolbarEffects.setVisibility(View.VISIBLE);
        toolbarEffectsFooter.setVisibility(View.VISIBLE);
        toolbarEffectDetails.setVisibility(View.GONE);
        toolbarSeekbar.setVisibility(View.GONE);
    }


    public class Painter extends AsyncTask<Void, Void, Void> {
        private ProgressDialog progressDialog;
        private int[] pixelData;
        private int width, height;
        int k = 0, i = 0, j = 0;

        @Override
        protected void onPreExecute(){
            super.onPreExecute();
            progressDialog = ProgressDialog.show(MainActivity.this, "Loading", "Please wait...", true);         
        }

        @Override
        protected Void doInBackground(Void... params) {
            // TODO Auto-generated method stub
            try {

                APJP2View mainImage = APIRequestManager.newLoad(uri, true);
                while (mainImage.getAdapter(SubimageDataView.class).getSubimageData() == null) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                // Get meta data
                MetaData metaData = null;
                if (mainImage.getAdapter(MetaDataView.class) != null)
                    metaData = mainImage.getAdapter(MetaDataView.class).getMetaData();


                ImageTransport imageData = mainImage.getSubimageData().getImageTransport();
                pixelData = imageData.getPixelData();  
                width = mainImage.getSubimageData().getWidth();
                height = mainImage.getSubimageData().getHeight();

            } catch (IOException e) {
                Log.d("HATA : ", "Dosya açılırken bir sorun oluştu!");
            }


            conf = Bitmap.Config.ARGB_8888;
            bm = Bitmap.createBitmap(width, height, conf); 


            Canvas canvas = new Canvas(bm);

            paint = new Paint(Paint.ANTI_ALIAS_FLAG);

            Log.d("Width", String.valueOf(width));
            Log.d("Height", String.valueOf(height));
            Log.d("PixelLength", String.valueOf(pixelData.length));

            for (i = 0; i < width; i++) {
                for (j = 0; j < height; j++) {
                    paint.setStyle(Paint.Style.FILL);
                    paint.setColor(pixelData[k]);
                    k++;
                    canvas.drawPoint(i, j, paint);
                    canvas.setBitmap(bm);
                }
            }

            imgPreview.setImageBitmap(bm);
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            progressDialog.dismiss();
        }

    }
}

我可以成功获取pixelData,但是绘图部分出现错误。绘图部分:

for (i = 0; i < width; i++) {
     for (j = 0; j < height; j++) {
          paint.setStyle(Paint.Style.FILL);
          paint.setColor(pixelData[k]);
          k++;
          canvas.drawPoint(i, j, paint);
          canvas.setBitmap(bm);
     }
}

在 Painter 类中。

pixelData 保存整数颜色值。我正在尝试在 imageView 上绘图。 那么我的错误在哪里? Logcat 日志:

07-27 09:12:36.795: W/dalvikvm(29734): threadid=11: thread exiting with uncaught exception (group=0x41715c08)
07-27 09:12:36.795: E/AndroidRuntime(29734): FATAL EXCEPTION: AsyncTask #1
07-27 09:12:36.795: E/AndroidRuntime(29734): Process: com.argenit.digitalpathology, PID: 29734
07-27 09:12:36.795: E/AndroidRuntime(29734): java.lang.RuntimeException: An error occured while executing doInBackground()
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.os.AsyncTask$3.done(AsyncTask.java:300)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at java.lang.Thread.run(Thread.java:841)
07-27 09:12:36.795: E/AndroidRuntime(29734): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6806)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1046)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.view.View.requestLayout(View.java:17209)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.view.View.requestLayout(View.java:17209)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.view.View.requestLayout(View.java:17209)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.view.View.requestLayout(View.java:17209)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.view.View.requestLayout(View.java:17209)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.view.View.requestLayout(View.java:17209)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.view.View.requestLayout(View.java:17209)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.widget.ImageView.setImageDrawable(ImageView.java:434)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.widget.ImageView.setImageBitmap(ImageView.java:449)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at com.argenit.pathology.MainActivity$Painter.doInBackground(MainActivity.java:333)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at com.argenit.pathology.MainActivity$Painter.doInBackground(MainActivity.java:1)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at android.os.AsyncTask$2.call(AsyncTask.java:288)
07-27 09:12:36.795: E/AndroidRuntime(29734):    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-27 09:12:36.795: E/AndroidRuntime(29734):    ... 4 more
07-27 09:12:37.070: D/dalvikvm(29734): GC_FOR_ALLOC freed 1755K, 30% free 10552K/15020K, paused 27ms, total 32ms
07-27 09:12:37.530: E/WindowManager(29734): android.view.WindowLeaked: Activity com.argenit.pathology.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{42228f98 V.E..... R......D 0,0-1160,340} that was originally added here
07-27 09:12:37.530: E/WindowManager(29734):     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:448)
07-27 09:12:37.530: E/WindowManager(29734):     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:267)
07-27 09:12:37.530: E/WindowManager(29734):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
07-27 09:12:37.530: E/WindowManager(29734):     at android.app.Dialog.show(Dialog.java:288)
07-27 09:12:37.530: E/WindowManager(29734):     at android.app.ProgressDialog.show(ProgressDialog.java:116)
07-27 09:12:37.530: E/WindowManager(29734):     at android.app.ProgressDialog.show(ProgressDialog.java:99)
07-27 09:12:37.530: E/WindowManager(29734):     at com.argenit.pathology.MainActivity$Painter.onPreExecute(MainActivity.java:278)
07-27 09:12:37.530: E/WindowManager(29734):     at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
07-27 09:12:37.530: E/WindowManager(29734):     at android.os.AsyncTask.execute(AsyncTask.java:535)
07-27 09:12:37.530: E/WindowManager(29734):     at com.argenit.pathology.MainActivity.btn_fileOpen_Click(MainActivity.java:204)
07-27 09:12:37.530: E/WindowManager(29734):     at java.lang.reflect.Method.invokeNative(Native Method)
07-27 09:12:37.530: E/WindowManager(29734):     at java.lang.reflect.Method.invoke(Method.java:515)
07-27 09:12:37.530: E/WindowManager(29734):     at android.view.View$1.onClick(View.java:3957)
07-27 09:12:37.530: E/WindowManager(29734):     at android.view.View.performClick(View.java:4626)
07-27 09:12:37.530: E/WindowManager(29734):     at android.view.View$PerformClick.run(View.java:19218)
07-27 09:12:37.530: E/WindowManager(29734):     at android.os.Handler.handleCallback(Handler.java:733)
07-27 09:12:37.530: E/WindowManager(29734):     at android.os.Handler.dispatchMessage(Handler.java:95)
07-27 09:12:37.530: E/WindowManager(29734):     at android.os.Looper.loop(Looper.java:157)
07-27 09:12:37.530: E/WindowManager(29734):     at android.app.ActivityThread.main(ActivityThread.java:5350)
07-27 09:12:37.530: E/WindowManager(29734):     at java.lang.reflect.Method.invokeNative(Native Method)
07-27 09:12:37.530: E/WindowManager(29734):     at java.lang.reflect.Method.invoke(Method.java:515)
07-27 09:12:37.530: E/WindowManager(29734):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
07-27 09:12:37.530: E/WindowManager(29734):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
07-27 09:12:37.530: E/WindowManager(29734):     at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • 只有创建视图层次结构的原始线程才能接触其视图。。您不能在后台线程中修改视图。 doInBackground 中不能有`imgPreview.setImageBitmap(bm);`
  • @Raghunandan 那么有什么解决方案吗?
  • 在 doInBackground 中进行所有不涉及视图的处理,然后在 ui 线程上更新您的 ui,即 onPostExecute
  • 完美,有效。谢谢@Raghunandan

标签: android bitmap android-asynctask


【解决方案1】:

您必须在 UI 线程上使用 setImageBitmap。

删除这部分:

    @Override
    protected Void doInBackground(Void... params) {
        ...

        imgPreview.setImageBitmap(bm);
        return null;
    }

并添加:

public class Painter extends AsyncTask<Void, Void, Bitmap> {           

     @Override
    protected Bitmap doInBackground(Void... params) {
        ...
        return bm;
    }

     @Override
    protected void onPostExecute(Bitmap result) {
        // runs on the UI Thread
        imgPreview.setImageBitmap(result);
        progressDialog.dismiss();
    }
}

【讨论】:

    【解决方案2】:

    您必须使用

    访问在 doInBackground() 之外声明的视图
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            imgPreview.setImageBitmap(bm)
        }
    });
    

    【讨论】:

      【解决方案3】:

      简单的代码为图像创建类 asynctask。

        private  class DownloadImageTask extends AsyncTask<String,Void,   Bitmap> {
      
          ImageView bmImage;
          public DownloadImageTask(ImageView bmImage){
              this.bmImage= bmImage;
      
          }
      
          protected Bitmap doInBackground(String... urls){
              String urldisplay = urls[0];
              Bitmap mIcon11 = null;
              try {
                  InputStream in= new java.net.URL(urldisplay).openStream();
                  mIcon11 = BitmapFactory.decodeStream(in);
              }catch (Exception e){
      
                  Log.e("Error", e.getMessage());
                  e.printStackTrace();
              }
      
              return mIcon11;
      
          }
      
          protected void onPostExecute(Bitmap result){
              bmImage.setImageBitmap(result);
          }
      
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-18
        相关资源
        最近更新 更多