summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/Utilities.java
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2014-08-04 10:53:22 -0700
committerSunny Goyal <sunnygoyal@google.com>2014-08-11 12:32:04 -0700
commit95abbb330ce9bbaf23594245f0f8a795c8118038 (patch)
tree3d72a2655eb05efd10c9d5c5e29cc40d2b40838b /src/com/android/launcher3/Utilities.java
parent6551b7ef07b4d73c096cbfb22002e080b498cbbb (diff)
downloadandroid_packages_apps_Trebuchet-95abbb330ce9bbaf23594245f0f8a795c8118038.tar.gz
android_packages_apps_Trebuchet-95abbb330ce9bbaf23594245f0f8a795c8118038.tar.bz2
android_packages_apps_Trebuchet-95abbb330ce9bbaf23594245f0f8a795c8118038.zip
Updating the virtual preloader UX.
> No click feedback when in preloader mode > No preloader UI when drawn in drag layer > The preloader consists of a background 9 patch image and a circular progress is drawn in the content region of the background. > The preloader is drawn in a slightly larget area than the actual bounds to make the circular progress more prominent compared to the icon. issue: 15835307 Change-Id: Ifec3d93ecf1fac994d1128b517da3797247e7ed6
Diffstat (limited to 'src/com/android/launcher3/Utilities.java')
-rw-r--r--src/com/android/launcher3/Utilities.java81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 0a711c5dd..87c2d7515 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -29,6 +29,7 @@ import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
@@ -39,6 +40,7 @@ import android.graphics.drawable.PaintDrawable;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.SparseArray;
import android.view.View;
import android.widget.Toast;
@@ -393,4 +395,83 @@ public final class Utilities {
return false;
}
}
+
+ /**
+ * This picks a dominant color, looking for high-saturation, high-value, repeated hues.
+ * @param bitmap The bitmap to scan
+ * @param samples The approximate max number of samples to use.
+ */
+ static int findDominantColorByHue(Bitmap bitmap, int samples) {
+ final int height = bitmap.getHeight();
+ final int width = bitmap.getWidth();
+ int sampleStride = (int) Math.sqrt((height * width) / samples);
+ if (sampleStride < 1) {
+ sampleStride = 1;
+ }
+
+ // This is an out-param, for getting the hsv values for an rgb
+ float[] hsv = new float[3];
+
+ // First get the best hue, by creating a histogram over 360 hue buckets,
+ // where each pixel contributes a score weighted by saturation, value, and alpha.
+ float[] hueScoreHistogram = new float[360];
+ float highScore = -1;
+ int bestHue = -1;
+
+ for (int y = 0; y < height; y += sampleStride) {
+ for (int x = 0; x < width; x += sampleStride) {
+ int argb = bitmap.getPixel(x, y);
+ int alpha = 0xFF & (argb >> 24);
+ if (alpha < 0x80) {
+ // Drop mostly-transparent pixels.
+ continue;
+ }
+ // Remove the alpha channel.
+ int rgb = argb | 0xFF000000;
+ Color.colorToHSV(rgb, hsv);
+ // Bucket colors by the 360 integer hues.
+ int hue = (int) hsv[0];
+ if (hue < 0 || hue >= hueScoreHistogram.length) {
+ // Defensively avoid array bounds violations.
+ continue;
+ }
+ float score = hsv[1] * hsv[2];
+ hueScoreHistogram[hue] += score;
+ if (hueScoreHistogram[hue] > highScore) {
+ highScore = hueScoreHistogram[hue];
+ bestHue = hue;
+ }
+ }
+ }
+
+ SparseArray<Float> rgbScores = new SparseArray<Float>();
+ int bestColor = 0xff000000;
+ highScore = -1;
+ // Go back over the RGB colors that match the winning hue,
+ // creating a histogram of weighted s*v scores, for up to 100*100 [s,v] buckets.
+ // The highest-scoring RGB color wins.
+ for (int y = 0; y < height; y += sampleStride) {
+ for (int x = 0; x < width; x += sampleStride) {
+ int rgb = bitmap.getPixel(x, y) | 0xff000000;
+ Color.colorToHSV(rgb, hsv);
+ int hue = (int) hsv[0];
+ if (hue == bestHue) {
+ float s = hsv[1];
+ float v = hsv[2];
+ int bucket = (int) (s * 100) + (int) (v * 10000);
+ // Score by cumulative saturation * value.
+ float score = s * v;
+ Float oldTotal = rgbScores.get(bucket);
+ float newTotal = oldTotal == null ? score : oldTotal + score;
+ rgbScores.put(bucket, newTotal);
+ if (newTotal > highScore) {
+ highScore = newTotal;
+ // All the colors in the winning bucket are very similar. Last in wins.
+ bestColor = rgb;
+ }
+ }
+ }
+ }
+ return bestColor;
+ }
}