title: Bitmap / Canvas: java.lang.IllegalArgumentException: width and height must be > 0
body: <p>I am trying to add a waveform visual to my already functioning app that will record a sound, and then play it back. The recording/playback code works fine, but when I tried to add the <a href="https://github.com/felixpalmer/android-visualizer" rel="nofollow noreferrer">com.pheelicks.app</a> visualizer, and record my own sound, then try to play it back, I get a crash when I hit my own play button. </p>
  
  <p>In his visualizer app, he provides his own mp3 sound files, which play through MediaPlayer. But since I also play my recorded sound through MediaPlayer, I figured it should be easy to adjust my code to include his visualizer part. But something is wrong.</p>
  
  <p>The strange part is that his code runs perfectly in my Android phone (Samsung Galaxy 5), I can see the visualizer to the music.</p>
  
  <p>I have tried to research similar problems, but I don't find answers there. I have tried <a href="https://stackoverflow.com/questions/20400541/java-lang-illegalargumentexception-width-and-height-must-be-0-when-setting-bi">this</a> and <a href="https://stackoverflow.com/questions/17605662/illegalargumentexception-width-and-height-must-be-0-while-loading-bitmap-from">this</a>, both similar errors, but I did not find a solution. </p>
  
  <p>The error seems to be coming from his code, the <strong>VisualizerView.java</strong> in the Bitmap part where <code>getWidth()</code> and <code>getHeight()</code> is called from <code>Canvas</code> in the <code>onDraw()</code> method. I also tried to log these values, but they are not showing up in my <code>LogCat</code>. I'm using Android Studio. Thanks for your help!</p>
  
  <p>EDIT:</p>
  
  <p>Ah, I see my <code>Log</code> statement did not work because it was placed after the point of the crash. I placed it right before the crash point:</p>
  
  <pre><code>if (mCanvasBitmap == null) {
          mCanvasBitmap = Bitmap.createBitmap(canvas.getWidth(),
                  canvas.getHeight(), Config.ARGB_8888);
      }
  </code></pre>
  
  <p>And I get this from LogCat: <code>Value of getWidth is 924 and value of getHeight is 0</code>. So the question is, why is the height zero?</p>
  
  <p><strong>VisualizerView.java</strong></p>
  
  <pre><code>package org.azurespot.waveform;
  
  /**
   * Created by mizu on 2/2/15.
   */
  import android.content.Context;
  import android.graphics.Bitmap;
  import android.graphics.Bitmap.Config;
  import android.graphics.Canvas;
  import android.graphics.Color;
  import android.graphics.Matrix;
  import android.graphics.Paint;
  import android.graphics.PorterDuff.Mode;
  import android.graphics.PorterDuffXfermode;
  import android.graphics.Rect;
  import android.media.MediaPlayer;
  import android.media.audiofx.Visualizer;
  import android.util.AttributeSet;
  import android.view.View;
  
  import java.util.HashSet;
  import java.util.Set;
  
  import static android.util.Log.d;
  
  /**
   * A class that draws visualizations of data received from a
   * {@link Visualizer.OnDataCaptureListener#onWaveFormDataCapture } and
   * {@link Visualizer.OnDataCaptureListener#onFftDataCapture }
   */
  public class VisualizerView extends View {
      private static final String TAG = "VisualizerView";
  
      private byte[] mBytes;
      private byte[] mFFTBytes;
      private Rect mRect = new Rect();
      private Visualizer mVisualizer;
  
      private Set&lt;Renderer&gt; mRenderers;
  
      private Paint mFlashPaint = new Paint();
      private Paint mFadePaint = new Paint();
  
      public VisualizerView(Context context, AttributeSet attrs, int defStyle) {
          super(context, attrs);
          init();
      }
  
      public VisualizerView(Context context, AttributeSet attrs) {
          this(context, attrs, 0);
      }
  
      public VisualizerView(Context context) {
          this(context, null, 0);
      }
  
      private void init() {
          mBytes = null;
          mFFTBytes = null;
  
          mFlashPaint.setColor(Color.argb(122, 255, 255, 255));
          mFadePaint.setColor(Color.argb(238, 255, 255, 255)); // Adjust alpha to change how quickly the image fades
          mFadePaint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));
  
          mRenderers = new HashSet&lt;Renderer&gt;();
      }
  
      /**
       * Links the visualizer to a player
       *
       * @param player - MediaPlayer instance to link to
       */
      public void link(MediaPlayer player) {
          if (player == null) {
              throw new NullPointerException("Cannot link to null MediaPlayer");
          }
  
          // Create the Visualizer object and attach it to our media player.
          mVisualizer = new Visualizer(player.getAudioSessionId());
          mVisualizer.setEnabled(false);
          mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
  
          // Pass through Visualizer data to VisualizerView
          Visualizer.OnDataCaptureListener captureListener = new Visualizer.OnDataCaptureListener() {
              @Override
              public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
                                                int samplingRate) {
                  updateVisualizer(bytes);
              }
  
              @Override
              public void onFftDataCapture(Visualizer visualizer, byte[] bytes,
                                           int samplingRate) {
                  updateVisualizerFFT(bytes);
              }
          };
  
          mVisualizer.setDataCaptureListener(captureListener,
                  Visualizer.getMaxCaptureRate() / 2, true, true);
  
          // Enabled Visualizer and disable when we're done with the stream
          mVisualizer.setEnabled(true);
          player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
              @Override
              public void onCompletion(MediaPlayer mediaPlayer) {
                  mVisualizer.setEnabled(false);
              }
          });
      }
  
      public void addRenderer(Renderer renderer) {
          if (renderer != null) {
              mRenderers.add(renderer);
          }
      }
  
      public void clearRenderers() {
          mRenderers.clear();
      }
  
      /**
       * Call to release the resources used by VisualizerView. Like with the
       * MediaPlayer it is good practice to call this method
       */
      public void release() {
          mVisualizer.release();
      }
  
      /**
       * Pass data to the visualizer. Typically this will be obtained from the
       * Android Visualizer.OnDataCaptureListener call back. See
       * {@link Visualizer.OnDataCaptureListener#onWaveFormDataCapture }
       *
       * @param bytes
       */
      public void updateVisualizer(byte[] bytes) {
          mBytes = bytes;
          invalidate();
      }
  
      /**
       * Pass FFT data to the visualizer. Typically this will be obtained from the
       * Android Visualizer.OnDataCaptureListener call back. See
       * {@link Visualizer.OnDataCaptureListener#onFftDataCapture }
       *
       * @param bytes
       */
      public void updateVisualizerFFT(byte[] bytes) {
          mFFTBytes = bytes;
          invalidate();
      }
  
      boolean mFlash = false;
  
      /**
       * Call this to make the visualizer flash. Useful for flashing at the start
       * of a song/loop etc...
       */
      public void flash() {
          mFlash = true;
          invalidate();
      }
  
      Bitmap mCanvasBitmap;
      Canvas mCanvas;
  
  
      @Override
      protected void onDraw(Canvas canvas) {
          super.onDraw(canvas);
  
          // Create canvas once we're ready to draw
          mRect.set(0, 0, getWidth(), getHeight());
  
          if (mCanvasBitmap == null) {
              mCanvasBitmap = Bitmap.createBitmap(canvas.getWidth(),
                      canvas.getHeight(), Config.ARGB_8888);
          }
  
          d("DEBUG", "Value of getWidth is " + canvas.getWidth()
                  + " and value of getHeight is " + canvas.getHeight());
          if (mCanvas == null) {
              mCanvas = new Canvas(mCanvasBitmap);
          }
  
          if (mBytes != null) {
              // Render all audio renderers
              AudioData audioData = new AudioData(mBytes);
              for (Renderer r : mRenderers) {
                  r.render(mCanvas, audioData, mRect);
              }
          }
  
          if (mFFTBytes != null) {
              // Render all FFT renderers
              FFTData fftData = new FFTData(mFFTBytes);
              for (Renderer r : mRenderers) {
                  r.render(mCanvas, fftData, mRect);
              }
          }
  
          // Fade out old contents
          mCanvas.drawPaint(mFadePaint);
  
          if (mFlash) {
              mFlash = false;
              mCanvas.drawPaint(mFlashPaint);
          }
  
          canvas.drawBitmap(mCanvasBitmap, new Matrix(), null);
      }
  }
  </code></pre>
  
  <p><strong>LogCat</strong></p>
  
  <pre><code>02-02 22:31:16.699  19125-19125/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
      Process: org.azurespot, PID: 19125
      java.lang.IllegalArgumentException: width and height must be &gt; 0
              at android.graphics.Bitmap.createBitmap(Bitmap.java:922)
              at android.graphics.Bitmap.createBitmap(Bitmap.java:901)
              at android.graphics.Bitmap.createBitmap(Bitmap.java:868)
              at org.azurespot.waveform.VisualizerView.onDraw(VisualizerView.java:176)
              at android.view.View.draw(View.java:15393)
              at android.view.View.getDisplayList(View.java:14287)
              at android.view.View.getDisplayList(View.java:14329)
              at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3284)
              at android.view.View.getDisplayList(View.java:14224)
              at android.view.View.getDisplayList(View.java:14329)
              at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3284)
              at android.view.View.getDisplayList(View.java:14224)
              at android.view.View.getDisplayList(View.java:14329)
              at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3284)
              at android.view.View.getDisplayList(View.java:14224)
              at android.view.View.getDisplayList(View.java:14329)
              at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3284)
              at android.view.View.getDisplayList(View.java:14224)
              at android.view.View.getDisplayList(View.java:14329)
              at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3284)
              at android.view.View.getDisplayList(View.java:14224)
              at android.view.View.getDisplayList(View.java:14329)
              at android.view.HardwareRenderer$GlRenderer.buildDisplayList(HardwareRenderer.java:1576)
              at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1455)
              at android.view.ViewRootImpl.draw(ViewRootImpl.java:2754)
              at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2620)
              at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2188)
              at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1249)
              at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6585)
              at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
              at android.view.Choreographer.doCallbacks(Choreographer.java:603)
              at android.view.Choreographer.doFrame(Choreographer.java:573)
              at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
              at android.os.Handler.handleCallback(Handler.java:733)
              at android.os.Handler.dispatchMessage(Handler.java:95)
              at android.os.Looper.loop(Looper.java:136)
              at android.app.ActivityThread.main(ActivityThread.java:5579)
              at java.lang.reflect.Method.invokeNative(Native Method)
              at java.lang.reflect.Method.invoke(Method.java:515)
              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
              at dalvik.system.NativeStart.main(Native Method)
  </code></pre>