Android.support.v7.graphics.Palette width and height must be> 0

I have code using the new Palette class and I get these crash reports in Crashlytics saying width and height must be > 0 . What is strange is what I call the palette code:

 if( bitmap == null || bitmap.getHeight() <= 0 || bitmap.getWidth() <= 0){ //do something }else{ Palette.Builder(bitmap).generate(new Palette.PaletteAsyncListener() { ..... } 

So I'm just not sure how it is possible that the bitmap suddenly does not have the correct height or width. I don’t know in which part of my code an exception occurs because the report includes only the material inside the palette class.

Here is the exception:

 java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:300) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.IllegalArgumentException: width and height must be > 0 at android.graphics.Bitmap.createBitmap(Bitmap.java:815) at android.graphics.Bitmap.createBitmap(Bitmap.java:794) at android.graphics.Bitmap.createBitmap(Bitmap.java:725) at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:601) at android.support.v7.graphics.Palette.scaleBitmapDown(Palette.java:282) at android.support.v7.graphics.Palette.access$100(Palette.java:67) at android.support.v7.graphics.Palette$Builder.generate(Palette.java:557) at android.support.v7.graphics.Palette$Builder$1.doInBackground(Palette.java:623) at android.support.v7.graphics.Palette$Builder$1.doInBackground(Palette.java:620) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:818) 

I am using the Palette class from com.android.support:palette-v7:23+

Any ideas on what might be wrong?

+6
source share
3 answers

You are probably trying to access the width and height of a user interface element before it is actually added to the layout.

That's why you got a width and height equal to 0, since the element is not actually there.

Use ViewTreeObserver http://developer.android.com/reference/android/view/ViewTreeObserver.html

  myView.getViewTreeObserver().addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { int finalHeight = myView.getMeasuredHeight(); int finalWidth = myView.getMeasuredWidth(); // Do your work here return true; } }); 

where myView will be your bitmap

0
source

I do not think your code has problems. I looked at the StackTrace that you posted.

 at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:601) at android.support.v7.graphics.Palette.scaleBitmapDown(Palette.java:282) 

If you look at the source code of Palette.java , you will find the scaling logic written in the scaleBitmapDown(Bitmap bitmap) method. If your "bitmap" is less than 100 pixels, then scaling is not performed. However, if your bitmap is larger than 100 pixels, Bitmap.createScaledBitmap() called. Now this method throws an IllegalArgumentException if the width or height is <0;

Thus, the bitmap you are passing does not have zero width, because if that were the case, you would never have reached the Bitmap.createScaledBitmap() method at all. However, I do not know what the real reason may be. Try looking at the source code of the exact Palette.java you are using.

0
source

The problem is with the concurrency problem: since you use Palette in async mode, when you call

 Palette.Builder(bitmap).generate(new Palette.PaletteAsyncListener() 

your bitmap is valid, but when Palette uses a bitmap in its own asynchronous logic, the bitmap may already be invalid or invalid (due to simultaneous manipulation).

It is easy to fix this problem there: since you do not need a high-resolution image to extract key colors, just specify a low-resolution bitmap created from your original one:

 if( bitmap == null || bitmap.getHeight() <= 0 || bitmap.getWidth() <= 0){ //do something }else{ //This resized bitmap is just an example: you should keep your bitmap //aspect ratio, and keep width and height < 100 Bitmap resizedBitmap = Bitmap.createScaledBitmap(myBitmap, 100, 100, false); Palette.Builder(resizedBitmap).generate(new Palette.PaletteAsyncListener() { ..... } 
0
source

All Articles