diff --git a/src/main/java/com/sangupta/colors/extract/android/AndroidColorExtractor.java b/src/main/java/com/sangupta/colors/extract/android/AndroidColorExtractor.java
index 6c4cc54..2550ce7 100644
--- a/src/main/java/com/sangupta/colors/extract/android/AndroidColorExtractor.java
+++ b/src/main/java/com/sangupta/colors/extract/android/AndroidColorExtractor.java
@@ -20,10 +20,8 @@
import java.util.ArrayList;
import java.util.List;
-import com.sangupta.colors.extract.android.Bitmap;
-import com.sangupta.colors.extract.android.ColorCutQuantizer;
-import com.sangupta.colors.extract.android.Palette;
-import com.sangupta.colors.extract.android.Target;
+import com.sangupta.colors.Swatch;
+import com.sangupta.colors.model.RGB;
/**
* This class is based on the Android source code to extract colors from a given
@@ -39,12 +37,12 @@
public class AndroidColorExtractor {
static final int DEFAULT_RESIZE_BITMAP_AREA = 112 * 112;
-
+
static final int DEFAULT_CALCULATE_NUMBER_COLORS = 16;
- private final List mSwatches;
+ private final List swatches;
- private final Bitmap mBitmap;
+ private final Bitmap bitmapImage;
private final List targets = new ArrayList();
@@ -57,23 +55,26 @@ public class AndroidColorExtractor {
private final List filters = new ArrayList();
/**
- * Construct a new {@link Builder} using a source {@link Bitmap}
+ *
+ * @param bitmap
*/
public AndroidColorExtractor(Bitmap bitmap) {
if (bitmap == null) {
throw new IllegalArgumentException("Bitmap is not valid");
}
- filters.add(PaletteFilter.DEFAULT_FILTER);
- mBitmap = bitmap;
- mSwatches = null;
+
+ this.filters.add(PaletteFilter.DEFAULT_FILTER);
+
+ this.bitmapImage = bitmap;
+ this.swatches = null;
// Add the default targets
- targets.add(Target.LIGHT_VIBRANT);
- targets.add(Target.VIBRANT);
- targets.add(Target.DARK_VIBRANT);
- targets.add(Target.LIGHT_MUTED);
- targets.add(Target.MUTED);
- targets.add(Target.DARK_MUTED);
+ this.targets.add(Target.LIGHT_VIBRANT);
+ this.targets.add(Target.VIBRANT);
+ this.targets.add(Target.DARK_VIBRANT);
+ this.targets.add(Target.LIGHT_MUTED);
+ this.targets.add(Target.MUTED);
+ this.targets.add(Target.DARK_MUTED);
}
/**
@@ -85,7 +86,7 @@ public AndroidColorExtractor(Bitmap bitmap) {
* faces then this value should be increased to ~24.
*/
public AndroidColorExtractor maximumColorCount(int colors) {
- maxColors = colors;
+ this.maxColors = colors;
return this;
}
@@ -104,8 +105,8 @@ public AndroidColorExtractor maximumColorCount(int colors) {
* should cover, or any value <= 0 to disable resizing.
*/
public AndroidColorExtractor resizeBitmapArea(final int area) {
- resizeArea = area;
- resizeMaxDimension = -1;
+ this.resizeArea = area;
+ this.resizeMaxDimension = -1;
return this;
}
@@ -114,7 +115,7 @@ public AndroidColorExtractor resizeBitmapArea(final int area) {
* automatically by {@link Palette}.
*/
public AndroidColorExtractor clearFilters() {
- filters.clear();
+ this.filters.clear();
return this;
}
@@ -128,6 +129,7 @@ public AndroidColorExtractor addFilter(PaletteFilter filter) {
if (filter != null) {
filters.add(filter);
}
+
return this;
}
@@ -139,8 +141,8 @@ public AndroidColorExtractor addFilter(PaletteFilter filter) {
*
*/
public AndroidColorExtractor addTarget(final Target target) {
- if (!targets.contains(target)) {
- targets.add(target);
+ if (!this.targets.contains(target)) {
+ this.targets.add(target);
}
return this;
}
@@ -150,8 +152,8 @@ public AndroidColorExtractor addTarget(final Target target) {
* automatically by {@link Palette}.
*/
public AndroidColorExtractor clearTargets() {
- if (targets != null) {
- targets.clear();
+ if (this.targets != null) {
+ this.targets.clear();
}
return this;
}
@@ -162,26 +164,26 @@ public AndroidColorExtractor clearTargets() {
public Palette generate() {
List swatches;
- if (mBitmap != null) {
+ if (this.bitmapImage != null) {
// We have a Bitmap so we need to use quantization to reduce the number of
// colors
// First we'll scale down the bitmap if needed
- final Bitmap bitmap = scaleBitmapDown(mBitmap);
+ final Bitmap bitmap = scaleBitmapDown(this.bitmapImage);
// Now generate a quantizer from the Bitmap
- final ColorCutQuantizer quantizer = new ColorCutQuantizer(getPixelsFromBitmap(bitmap), maxColors,
- filters.isEmpty() ? null : filters.toArray(new PaletteFilter[filters.size()]));
+ final ColorCutQuantizer quantizer = new ColorCutQuantizer(getPixelsFromBitmap(bitmap), this.maxColors,
+ this.filters.isEmpty() ? null : this.filters.toArray(new PaletteFilter[this.filters.size()]));
swatches = quantizer.getQuantizedColors();
} else {
// Else we're using the provided swatches
- swatches = mSwatches;
+ swatches = this.swatches;
}
// Now create a Palette instance
- final Palette palette = new Palette(swatches, targets);
+ final Palette palette = new Palette(swatches, this.targets);
// And make it generate itself
palette.generate();
@@ -198,15 +200,15 @@ private int[] getPixelsFromBitmap(Bitmap bitmap) {
private Bitmap scaleBitmapDown(final Bitmap bitmap) {
double scaleRatio = -1;
- if (resizeArea > 0) {
+ if (this.resizeArea > 0) {
final int bitmapArea = bitmap.getWidth() * bitmap.getHeight();
- if (bitmapArea > resizeArea) {
- scaleRatio = Math.sqrt(resizeArea / (double) bitmapArea);
+ if (bitmapArea > this.resizeArea) {
+ scaleRatio = Math.sqrt(this.resizeArea / (double) bitmapArea);
}
- } else if (resizeMaxDimension > 0) {
+ } else if (this.resizeMaxDimension > 0) {
final int maxDimension = Math.max(bitmap.getWidth(), bitmap.getHeight());
- if (maxDimension > resizeMaxDimension) {
- scaleRatio = resizeMaxDimension / (double) maxDimension;
+ if (maxDimension > this.resizeMaxDimension) {
+ scaleRatio = this.resizeMaxDimension / (double) maxDimension;
}
}
@@ -215,7 +217,8 @@ private Bitmap scaleBitmapDown(final Bitmap bitmap) {
return bitmap;
}
- return Bitmap.createScaledBitmap(bitmap, (int) Math.ceil(bitmap.getWidth() * scaleRatio), (int) Math.ceil(bitmap.getHeight() * scaleRatio));
+ return Bitmap.createScaledBitmap(bitmap, (int) Math.ceil(bitmap.getWidth() * scaleRatio),
+ (int) Math.ceil(bitmap.getHeight() * scaleRatio));
}
/**
@@ -229,10 +232,10 @@ private Bitmap scaleBitmapDown(final Bitmap bitmap) {
* @return A Color Hex String
*/
public static int getColor(BufferedImage image) {
- if(image == null) {
+ if (image == null) {
throw new IllegalArgumentException("Image cannot be null");
}
-
+
AndroidColorExtractor extractor = new AndroidColorExtractor(new Bitmap(image));
Palette palette = extractor.generate();
PaletteSwatch swatch = palette.getVibrantSwatch();
@@ -248,5 +251,40 @@ public static int getColor(BufferedImage image) {
int color = swatch.getRgb();
return color;
}
-
+
+ /**
+ * Get a {@link Swatch} of all dominant colors.
+ *
+ * @param image the {@link BufferedImage} to use
+ *
+ * @return
+ */
+ public static Swatch getSwatch(BufferedImage image) {
+ if (image == null) {
+ throw new IllegalArgumentException("Image cannot be null");
+ }
+
+ AndroidColorExtractor extractor = new AndroidColorExtractor(new Bitmap(image));
+ Palette palette = extractor.generate();
+
+ Swatch swatch = new Swatch<>();
+ addToSwatch(swatch, palette.getVibrantColor());
+
+ return swatch;
+ }
+
+ /**
+ * Convert android swatch color to {@link RGB} color and add it to the
+ * {@link Swatch}.
+ *
+ * @param swatch
+ * @param color
+ */
+ private static void addToSwatch(Swatch swatch, int color) {
+ if (color < 0) {
+ return;
+ }
+
+ swatch.add(new RGB(color));
+ }
}
diff --git a/src/main/java/com/sangupta/colors/extract/android/Palette.java b/src/main/java/com/sangupta/colors/extract/android/Palette.java
index 60a8e2a..5376f85 100644
--- a/src/main/java/com/sangupta/colors/extract/android/Palette.java
+++ b/src/main/java/com/sangupta/colors/extract/android/Palette.java
@@ -62,38 +62,38 @@ public final class Palette {
static final boolean LOG_TIMINGS = false;
- private final List mSwatches;
+ private final List swatches;
- private final List mTargets;
+ private final List targets;
- private final Map mSelectedSwatches;
+ private final Map selectedSwatches;
- private final SparseBooleanArray mUsedColors;
+ private final SparseBooleanArray usedColors;
- private final PaletteSwatch mDominantSwatch;
+ private final PaletteSwatch dominantSwatch;
Palette(List swatches, List targets) {
- mSwatches = swatches;
- mTargets = targets;
+ this.swatches = swatches;
+ this.targets = targets;
- mUsedColors = new SparseBooleanArray();
- mSelectedSwatches = new LinkedHashMap();
+ this.usedColors = new SparseBooleanArray();
+ this.selectedSwatches = new LinkedHashMap();
- mDominantSwatch = findDominantSwatch();
+ this.dominantSwatch = findDominantSwatch();
}
/**
* Returns all of the swatches which make up the palette.
*/
public List getSwatches() {
- return Collections.unmodifiableList(mSwatches);
+ return Collections.unmodifiableList(this.swatches);
}
/**
* Returns the targets used to generate this palette.
*/
public List getTargets() {
- return Collections.unmodifiableList(mTargets);
+ return Collections.unmodifiableList(this.targets);
}
/**
@@ -156,8 +156,8 @@ public PaletteSwatch getDarkMutedSwatch() {
* @param defaultColor value to return if the swatch isn't available
* @see #getVibrantSwatch()
*/
- public int getVibrantColor(final int defaultColor) {
- return getColorForTarget(Target.VIBRANT, defaultColor);
+ public int getVibrantColor() {
+ return getColorForTarget(Target.VIBRANT);
}
/**
@@ -166,8 +166,8 @@ public int getVibrantColor(final int defaultColor) {
* @param defaultColor value to return if the swatch isn't available
* @see #getLightVibrantSwatch()
*/
- public int getLightVibrantColor(final int defaultColor) {
- return getColorForTarget(Target.LIGHT_VIBRANT, defaultColor);
+ public int getLightVibrantColor() {
+ return getColorForTarget(Target.LIGHT_VIBRANT);
}
/**
@@ -176,8 +176,8 @@ public int getLightVibrantColor(final int defaultColor) {
* @param defaultColor value to return if the swatch isn't available
* @see #getDarkVibrantSwatch()
*/
- public int getDarkVibrantColor(final int defaultColor) {
- return getColorForTarget(Target.DARK_VIBRANT, defaultColor);
+ public int getDarkVibrantColor() {
+ return getColorForTarget(Target.DARK_VIBRANT);
}
/**
@@ -186,8 +186,8 @@ public int getDarkVibrantColor(final int defaultColor) {
* @param defaultColor value to return if the swatch isn't available
* @see #getMutedSwatch()
*/
- public int getMutedColor(final int defaultColor) {
- return getColorForTarget(Target.MUTED, defaultColor);
+ public int getMutedColor() {
+ return getColorForTarget(Target.MUTED);
}
/**
@@ -196,8 +196,8 @@ public int getMutedColor(final int defaultColor) {
* @param defaultColor value to return if the swatch isn't available
* @see #getLightMutedSwatch()
*/
- public int getLightMutedColor(final int defaultColor) {
- return getColorForTarget(Target.LIGHT_MUTED, defaultColor);
+ public int getLightMutedColor() {
+ return getColorForTarget(Target.LIGHT_MUTED);
}
/**
@@ -206,8 +206,8 @@ public int getLightMutedColor(final int defaultColor) {
* @param defaultColor value to return if the swatch isn't available
* @see #getDarkMutedSwatch()
*/
- public int getDarkMutedColor(final int defaultColor) {
- return getColorForTarget(Target.DARK_MUTED, defaultColor);
+ public int getDarkMutedColor() {
+ return getColorForTarget(Target.DARK_MUTED);
}
/**
@@ -215,7 +215,7 @@ public int getDarkMutedColor(final int defaultColor) {
* {@code null} if one could not be found.
*/
public PaletteSwatch getSwatchForTarget(final Target target) {
- return mSelectedSwatches.get(target);
+ return this.selectedSwatches.get(target);
}
/**
@@ -224,9 +224,9 @@ public PaletteSwatch getSwatchForTarget(final Target target) {
*
* @param defaultColor value to return if the swatch isn't available
*/
- public int getColorForTarget(final Target target, final int defaultColor) {
+ public int getColorForTarget(final Target target) {
PaletteSwatch swatch = getSwatchForTarget(target);
- return swatch != null ? swatch.getRgb() : defaultColor;
+ return swatch != null ? swatch.getRgb() : -1;
}
/**
@@ -238,7 +238,7 @@ public int getColorForTarget(final Target target, final int defaultColor) {
*
*/
public PaletteSwatch getDominantSwatch() {
- return mDominantSwatch;
+ return this.dominantSwatch;
}
/**
@@ -249,20 +249,21 @@ public PaletteSwatch getDominantSwatch() {
* @see #getDominantSwatch()
*/
public int getDominantColor(int defaultColor) {
- return mDominantSwatch != null ? mDominantSwatch.getRgb() : defaultColor;
+ return this.dominantSwatch != null ? this.dominantSwatch.getRgb() : defaultColor;
}
void generate() {
// We need to make sure that the scored targets are generated first. This is so
// that
// inherited targets have something to inherit from
- for (int i = 0, count = mTargets.size(); i < count; i++) {
- final Target target = mTargets.get(i);
+ for (int i = 0, count = this.targets.size(); i < count; i++) {
+ final Target target = this.targets.get(i);
target.normalizeWeights();
- mSelectedSwatches.put(target, generateScoredTarget(target));
+ this.selectedSwatches.put(target, generateScoredTarget(target));
}
+
// We now clear out the used colors
- mUsedColors.clear();
+ this.usedColors.clear();
}
private PaletteSwatch generateScoredTarget(final Target target) {
@@ -270,7 +271,7 @@ private PaletteSwatch generateScoredTarget(final Target target) {
if (maxScoreSwatch != null && target.isExclusive()) {
// If we have a swatch, and the target is exclusive, add the color to the used
// list
- mUsedColors.append(maxScoreSwatch.getRgb(), true);
+ this.usedColors.append(maxScoreSwatch.getRgb(), true);
}
return maxScoreSwatch;
}
@@ -278,8 +279,8 @@ private PaletteSwatch generateScoredTarget(final Target target) {
private PaletteSwatch getMaxScoredSwatchForTarget(final Target target) {
float maxScore = 0;
PaletteSwatch maxScoreSwatch = null;
- for (int i = 0, count = mSwatches.size(); i < count; i++) {
- final PaletteSwatch swatch = mSwatches.get(i);
+ for (int i = 0, count = this.swatches.size(); i < count; i++) {
+ final PaletteSwatch swatch = this.swatches.get(i);
if (shouldBeScoredForTarget(swatch, target)) {
final float score = generateScore(swatch, target);
if (maxScoreSwatch == null || score > maxScore) {
@@ -298,7 +299,7 @@ private boolean shouldBeScoredForTarget(final PaletteSwatch swatch, final Target
final float hsl[] = swatch.getHsl();
return hsl[1] >= target.getMinimumSaturation() && hsl[1] <= target.getMaximumSaturation()
&& hsl[2] >= target.getMinimumLightness() && hsl[2] <= target.getMaximumLightness()
- && !mUsedColors.get(swatch.getRgb());
+ && !this.usedColors.get(swatch.getRgb());
}
private float generateScore(PaletteSwatch swatch, Target target) {
@@ -308,7 +309,7 @@ private float generateScore(PaletteSwatch swatch, Target target) {
float luminanceScore = 0;
float populationScore = 0;
- final int maxPopulation = mDominantSwatch != null ? mDominantSwatch.getPopulation() : 1;
+ final int maxPopulation = this.dominantSwatch != null ? this.dominantSwatch.getPopulation() : 1;
if (target.getSaturationWeight() > 0) {
saturationScore = target.getSaturationWeight() * (1f - Math.abs(hsl[1] - target.getTargetSaturation()));
@@ -326,8 +327,8 @@ private float generateScore(PaletteSwatch swatch, Target target) {
private PaletteSwatch findDominantSwatch() {
int maxPop = Integer.MIN_VALUE;
PaletteSwatch maxSwatch = null;
- for (int i = 0, count = mSwatches.size(); i < count; i++) {
- PaletteSwatch swatch = mSwatches.get(i);
+ for (int i = 0, count = this.swatches.size(); i < count; i++) {
+ PaletteSwatch swatch = this.swatches.get(i);
if (swatch.getPopulation() > maxPop) {
maxSwatch = swatch;
maxPop = swatch.getPopulation();