画布逐点绘制

时间:2015-06-30 10:17:21

标签: android

public class MainActivity extends ActionBarActivity implements OnClickListener {
    Button btn;
    ImageView view;
    Bitmap bm;
    Canvas canvas;
    Paint paint;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn = (Button) super.findViewById(R.id.button1);
        btn.setOnClickListener(this);

        view = (ImageView) super.findViewById(R.id.imageView1);
        Bitmap.Config conf = Bitmap.Config.ARGB_8888;
        bm = Bitmap.createBitmap(200, 200, conf); 
        Canvas canvas = new Canvas(bm);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);
        canvas.drawCircle(50, 50, 10, paint);
        view.setImageBitmap(bm);


    }

    @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);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        try 
        {
          // Start by customizing the error and warning services in Kakadu
          Kdu_sysout_message sysout =
            new Kdu_sysout_message(false); // Non-throwing message printer
          Kdu_sysout_message syserr =
            new Kdu_sysout_message(true); // Exception-throwing message printer
          Kdu_message_formatter pretty_sysout =
            new Kdu_message_formatter(sysout); // Non-throwing formatted printer
          Kdu_message_formatter pretty_syserr =
            new Kdu_message_formatter(syserr); // Throwing formatted printer

          Kdu_global.Kdu_customize_warnings(pretty_sysout);
          Kdu_global.Kdu_customize_errors(pretty_syserr);
          Kdu_simple_file_source raw_src = null; // Must be disposed last
          Jp2_family_src family_src = new Jp2_family_src(); // Dispose last
          Jpx_source wrapped_src = new Jpx_source(); // Dispose before codestream
          Kdu_codestream codestream = new Kdu_codestream(); // Needs `destroy'
          Kdu_channel_mapping channels = new Kdu_channel_mapping();
          Kdu_region_decompressor decompressor = new Kdu_region_decompressor();

          try 
          { 
            // Open input file as raw codestream or a JP2/JPX file
            String fname = Environment.getExternalStorageDirectory().getPath() + "/Android/CB.jp2";
            family_src.Open(fname); // Generates an error if file doesn't exist
            Jpx_layer_source xlayer = null;
            Jpx_codestream_source xstream = null;
            int success = wrapped_src.Open(family_src,true);
            Kdu_compressed_source input=null; // Allows us to refer to compressed
            // data source associated with either a raw codestream
            // file or a JP2/JPX embedded codestream.
            if (success < 0)
            { // Must open as raw file
              family_src.Close();
              wrapped_src.Close();
              raw_src = new Kdu_simple_file_source(fname);
              input = raw_src;
            }
            else
            { // Succeeded in opening as wrapped JP2/JPX source
              xlayer = wrapped_src.Access_layer(0);
              xstream = wrapped_src.Access_codestream(xlayer.Get_codestream_id(0));
              input = xstream.Open_stream();
            }
         // Create the code-stream management machinery
            codestream.Create(input);
            if (xlayer != null)
              channels.Configure(xlayer.Access_colour(0),xlayer.Access_channels(),
                                 xstream.Get_codestream_id(),
                                 xstream.Access_palette(),
                                 xstream.Access_dimensions());
            else
              channels.Configure(codestream);
            int ref_component = channels.Get_source_component(0);
            Kdu_coords ref_expansion =
              determine_reference_expansion(ref_component,channels,codestream);

            // Determine dimensions for the rendered result & start decompressor
            Kdu_dims view_dims =
              decompressor.Get_rendered_image_dims(codestream,channels,-1,
                                        0,ref_expansion,new Kdu_coords(1,1),
                                        Kdu_global.KDU_WANT_OUTPUT_COMPONENTS);
            Kdu_coords view_size = view_dims.Access_size();
                // Note: changes in `view_size' will also affect `view_dims'
            //start_display(view_size);
            Kdu_coords display_size =
              new Kdu_coords(200,200);
            if (view_size.Get_x() > display_size.Get_x())
              view_size.Set_x(display_size.Get_x());
            if (view_size.Get_y() > display_size.Get_y())
              view_size.Set_y(display_size.Get_y());
            decompressor.Start(codestream,channels,-1,0,16384,view_dims,
                               ref_expansion,new Kdu_coords(1,1),false,
                               Kdu_global.KDU_WANT_OUTPUT_COMPONENTS);

            // Render incrementally.
            int region_buf_size = view_size.Get_x() * 60;
            int[] region_buf = new int[region_buf_size];
            Kdu_dims new_region = new Kdu_dims();
            Kdu_dims incomplete_region = new Kdu_dims();
            incomplete_region.Assign(view_dims);
            while (decompressor.Process(region_buf,view_dims.Access_pos(),
                                        0,0,region_buf_size,
                                        incomplete_region,new_region))
            { // Transfer decompressed region into the main buffer
              Kdu_coords offset =
                new_region.Access_pos().Minus(view_dims.Access_pos());
              Log.d("OFFSET", offset.Get_x() + "," + offset.Get_y());
              Log.d("COLOR CODES", "" + region_buf[0] + region_buf[1] + region_buf[2] + region_buf[3]);
              put_region(view_size.Get_x(),view_size.Get_y(),
                                 new_region.Access_size().Get_x(),
                                 new_region.Access_size().Get_y(),
                                 offset.Get_x(),offset.Get_y(),region_buf);
            }
            decompressor.Finish();
            //display.repaint();
          }
          catch (KduException e)
          { // See END NOTE 2
            System.out.println("[Caught exception \"" + e.getMessage() +
                               "\" -- code " +
                               Integer.toHexString(e.Get_kdu_exception_code()) +
                               "]");
          }
          // Cleanup: Disposal must happen in the right order
          // See END NOTE 3 for a discussion of Kakadu object disposal
          decompressor.Native_destroy();
          channels.Native_destroy();
          if (codestream.Exists()) codestream.Destroy();
          if (raw_src != null) raw_src.Native_destroy();
          wrapped_src.Native_destroy();
          family_src.Native_destroy();
        }
        catch (KduException e)
        { // See END NOTE 2
          System.out.println("[Caught exception during creation of key objects!]");
        }
    }

    private static Kdu_coords determine_reference_expansion(int reference_component, Kdu_channel_mapping channels, Kdu_codestream codestream) throws KduException{
        int c;
        Kdu_coords ref_subs = new Kdu_coords();
        Kdu_coords subs = new Kdu_coords();
        codestream.Get_subsampling(reference_component, ref_subs);
        Kdu_coords min_subs = new Kdu_coords();
        min_subs.Assign(ref_subs);
        for(c = 0; c < channels.Get_num_channels(); c++){
            codestream.Get_subsampling(channels.Get_source_component(c), subs);
            if(subs.Get_x() < min_subs.Get_x())
                min_subs.Set_x(subs.Get_x());
            if (subs.Get_y() < min_subs.Get_y())
                min_subs.Set_y(subs.Get_y());
        }

        Kdu_coords expansion = new Kdu_coords();
        expansion.Set_x(ref_subs.Get_x() / min_subs.Get_x());
        expansion.Set_y(ref_subs.Get_y() / min_subs.Get_y());
        for (c=0; c < channels.Get_num_channels(); c++)
          {
            codestream.Get_subsampling(channels.Get_source_component(c),subs);
            if ((((subs.Get_x() * expansion.Get_x()) % ref_subs.Get_x()) != 0) ||
                (((subs.Get_y() * expansion.Get_y()) % ref_subs.Get_y()) != 0))
              {
                Kdu_global.Kdu_print_error(
                  "The supplied JP2 file contains colour channels " +
                  "whose sub-sampling factors are not integer " +
                  "multiples of one another.");
                codestream.Apply_input_restrictions(0,1,0,0,null,
                                       Kdu_global.KDU_WANT_OUTPUT_COMPONENTS);
                channels.Configure(codestream);
                expansion = new Kdu_coords(1,1);
              }
          }
        return expansion;
    }



    class Kdu_sysout_message extends Kdu_message
    {
      public Kdu_sysout_message(boolean raise_exception)
      {
        this.raise_exception_on_end_of_message = raise_exception;
      }
      public void Put_text(String text)
      { // Implements the C++ callback function `kdu_message::put_text'
        System.out.print(text);
      }
      public void Flush(boolean end_of_message) throws KduException
      { // Implements the C++ callback function `kdu_message::flush'.
        if (end_of_message && raise_exception_on_end_of_message)
        throw new KduException(Kdu_global.KDU_ERROR_EXCEPTION,
                                   "In `Kdu_sysout_message'.");
      }
      private boolean raise_exception_on_end_of_message;
    }

    public void put_region(int view_width, int view_height, int reg_width, int reg_height, int reg_off_x, int reg_off_y, int[] reg_buf){
        int[] img_buf;
        if (bm == null){
            img_buf = new int[view_width*view_height];
        }

        int dest_idx = reg_off_x + reg_off_y*view_width;
        int src_idx = 0;
        int extra_row_gap = view_width - reg_width;
        int i, j;
        for (j=0; j < reg_height; j++, dest_idx+=extra_row_gap){
        for (i=0; i < reg_width; i++, src_idx++, dest_idx++){
            //Log.d("Test", i + "," + "," + j + "," + reg_buf[src_idx]);
            //bm.setPixel(i, j, Color.rgb(45, 127, 0));
            paint.setColor(reg_buf[src_idx]);
            Log.d("Paint", paint.toString());
            canvas.drawPoint(i, j, paint);
        }
        }//for
    }
}

reg_buf [src_idx]是一个颜色代码。

我想在图像视图上逐点并动态地绘制画布。

但是我收到了一个错误,最后一行的零点异常, canvas.drawPoint(i,j,paint);

我该如何解决这个问题?

LogCat错误:

  

06-30 13:16:34.991:E / AndroidRuntime(1517):致命异常:主要   06-30 13:16:34.991:E / AndroidRuntime(1517):进程:com.xxxx.xxxx,PID:1517   06-30 13:16:34.991:E / AndroidRuntime(1517):java.lang.NullPointerException   06-30 13:16:34.991:E / AndroidRuntime(1517):at com.xxxx.xxxx.MainActivity.put_region(MainActivity.java:277)   06-30 13:16:34.991:E / AndroidRuntime(1517):at com.xxxx.xxxx.MainActivity.onClick(MainActivity.java:173)   06-30 13:16:34.991:E / AndroidRuntime(1517):在android.view.View.performClick(View.java:4626)   06-30 13:16:34.991:E / AndroidRuntime(1517):在android.view.View $ PerformClick.run(View.java:19218)   06-30 13:16:34.991:E / AndroidRuntime(1517):在android.os.Handler.handleCallback(Handler.java:733)   06-30 13:16:34.991:E / AndroidRuntime(1517):在android.os.Handler.dispatchMessage(Handler.java:95)   06-30 13:16:34.991:E / AndroidRuntime(1517):在android.os.Looper.loop(Looper.java:157)   06-30 13:16:34.991:E / AndroidRuntime(1517):在android.app.ActivityThread.main(ActivityThread.java:5350)   06-30 13:16:34.991:E / AndroidRuntime(1517):at java.lang.reflect.Method.invokeNative(Native Method)   06-30 13:16:34.991:E / AndroidRuntime(1517):at java.lang.reflect.Method.invoke(Method.java:515)   06-30 13:16:34.991:E / AndroidRuntime(1517):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1265)   06-30 13:16:34.991:E / AndroidRuntime(1517):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)   06-30 13:16:34.991:E / AndroidRuntime(1517):at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:1)

当您尝试引用未初始化的方法或对象成员时,抛出

NullPointerException。让我们看看引发异常的行:

canvas.drawPoint(i, j, paint);

这里有什么null

  1. canvas可以为null,即使它已在onCreate中初始化。如果canvasnull,则需要对其进行初始化。

  2. ij是在循环中初始化的数字,因此这些不是问题的根源。

  3. 如果paintnull,那么在drawPoint内可能会抛出异常,但是,我们可以将其排除,因为setColor没有抛出NullPointerException

  4. 如您所见,canvasnull。但是,如果你在onCreate内初始化它怎么可能呢?答案是:你没有初始化它。您已使用

    初始化了一个局部变量
    Canvas canvas = new Canvas(bm);
    

    如果你没有声明它,只需使用对象的成员,那么就不应该抛出异常。所以你应该将行改为

    canvas = new Canvas(bm);