如果您使用Windows 7,則可以理解爲什麼我要查找圖像中的主色。將鼠標懸停在任務欄上的程序後,該特定程序會根據圖標中最主要的顏色進行更改。我注意到了其他程序中使用的這種技術,但無法記住它們。查找Android中可支配圖像的主色顏色
我可以看到這在我用來開發應用程序的許多UI技術中很有用,而且我想知道如何從Android可繪製資源中找到最常見的顏色。
如果您使用Windows 7,則可以理解爲什麼我要查找圖像中的主色。將鼠標懸停在任務欄上的程序後,該特定程序會根據圖標中最主要的顏色進行更改。我注意到了其他程序中使用的這種技術,但無法記住它們。查找Android中可支配圖像的主色顏色
我可以看到這在我用來開發應用程序的許多UI技術中很有用,而且我想知道如何從Android可繪製資源中找到最常見的顏色。
在Android中5.0棒棒糖,加入類,以幫助提取有用顏色的位圖。 0123.類,在android.support.v7中找到。圖形,可以提取顏色如下:
這個Android培訓頁面提供您需要使用該類的所有詳細信息(我在Android Studio中自己嘗試過這是非常簡單):http://developer.android.com/training/material/drawables.html#ColorExtract
引述:
Android的支持庫R21以上包括Palette 類,它可以讓你從圖像中提取突出的顏色。若要 提取這些顏色,請在加載圖像的後臺線程中將Bitmap對象傳遞給Palette.generate() 靜態方法。如果 你不能使用線程,調用Palette.generateAsync()方法和 提供一個監聽器來代替。*
可以使用的getter方法 在Palette類檢索圖像最突出的顏色,這樣的作爲Palette.getVibrantColor。
要使用調色板類在你的項目中,添加以下搖籃 依賴於你的應用程序的模塊:
dependencies { ... compile 'com.android.support:palette-v7:21.0.+' }
*如果你需要使用generateAsync(),方法如下:
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
public void onGenerated(Palette palette) {
// Do something with colors...
}
});
編輯: 由於問題問如何從可繪製資源中提取顏色,您首先必須將drawable轉換爲位圖才能使用我描述的技巧。幸運的是,這是一個使用BitmapFactory很簡單:
Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.icon_resource);`
如果您想試用Palette類提取的顏色,請在Play商店中查看我的應用:https://play.google.com/store/apps/details?id = com.tonyw.sampleapps.palettecolorextraction。你可以在GitHub上找到它的源代碼:https://github.com/tony-w/PaletteColorExtraction –
優秀的答案。這使得大多數可用的庫和方法變得冗餘。 – Baz
我認爲這將是最好的解釋一切,這樣會更清晰...... –
循環遍歷所有像素的顏色數據並平均顏色值,忽略任何灰色或透明的陰影。我相信這是微軟在Windows 7基於最近的博客文章做的。
編輯
的博客文章:http://blogs.msdn.com/b/oldnewthing/archive/2011/12/06/10244432.aspx
此鏈接顯示Chrome瀏覽器如何挑選主色也可能會有所幫助。 http://www.quora.com/Google-Chrome/How-does-Chrome-pick-the-color-for-the-stripes-on-the-Most-visited-page-thumbnails
我希望有一個API函數深埋在某個地方。這是很好的信息 – styler1972
我發現了一個簡單的黑客:複製爲1x1位圖並獲取顏色:http://aerilys.fr/blog/?p = 1341 – radley
該類迭代通過位圖並返回最主要的顏色。 如有必要,請隨時清理代碼。
public class ImageColour {
String colour;
public ImageColour(Bitmap image) throws Exception {
int height = image.getHeight();
int width = image.getWidth();
Map m = new HashMap();
for(int i=0; i < width ; i++){
for(int j=0; j < height ; j++){
int rgb = image.getPixel(i, j);
int[] rgbArr = getRGBArr(rgb);
if (!isGray(rgbArr)) {
Integer counter = (Integer) m.get(rgb);
if (counter == null)
counter = 0;
counter++;
m.put(rgb, counter);
}
}
}
String colourHex = getMostCommonColour(m);
}
public static String getMostCommonColour(Map map) {
List list = new LinkedList(map.entrySet());
Collections.sort(list, new Comparator() {
public int compare(Object o1, Object o2) {
return ((Comparable) ((Map.Entry) (o1)).getValue())
.compareTo(((Map.Entry) (o2)).getValue());
}
});
Map.Entry me = (Map.Entry)list.get(list.size()-1);
int[] rgb= getRGBArr((Integer)me.getKey());
return Integer.toHexString(rgb[0])+" "+Integer.toHexString(rgb[1])+" "+Integer.toHexString(rgb[2]);
}
public static int[] getRGBArr(int pixel) {
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel) & 0xff;
return new int[]{red,green,blue};
}
public static boolean isGray(int[] rgbArr) {
int rgDiff = rgbArr[0] - rgbArr[1];
int rbDiff = rgbArr[0] - rgbArr[2];
int tolerance = 10;
if (rgDiff > tolerance || rgDiff < -tolerance)
if (rbDiff > tolerance || rbDiff < -tolerance) {
return false;
}
return true;
}
public String returnColour() {
if (colour.length() == 6) {
return colour.replaceAll("\\s", "");
} else {
return "ffffff";
}
}
得到六角只需撥打 returnColour();
我建議誰使用這種方法來玩容忍變量。根據您設置的值,算法運行得更快或更慢。 –
我寫我自己的方法來獲取主色:
方法1(我的技術)
ARGB_4444
色彩空間最大值結合到顯性RGB顏色
public int getDominantColor1(Bitmap bitmap) {
if (bitmap == null)
throw new NullPointerException();
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int size = width * height;
int pixels[] = new int[size];
Bitmap bitmap2 = bitmap.copy(Bitmap.Config.ARGB_4444, false);
bitmap2.getPixels(pixels, 0, width, 0, 0, width, height);
final List<HashMap<Integer, Integer>> colorMap = new ArrayList<HashMap<Integer, Integer>>();
colorMap.add(new HashMap<Integer, Integer>());
colorMap.add(new HashMap<Integer, Integer>());
colorMap.add(new HashMap<Integer, Integer>());
int color = 0;
int r = 0;
int g = 0;
int b = 0;
Integer rC, gC, bC;
for (int i = 0; i < pixels.length; i++) {
color = pixels[i];
r = Color.red(color);
g = Color.green(color);
b = Color.blue(color);
rC = colorMap.get(0).get(r);
if (rC == null)
rC = 0;
colorMap.get(0).put(r, ++rC);
gC = colorMap.get(1).get(g);
if (gC == null)
gC = 0;
colorMap.get(1).put(g, ++gC);
bC = colorMap.get(2).get(b);
if (bC == null)
bC = 0;
colorMap.get(2).put(b, ++bC);
}
int[] rgb = new int[3];
for (int i = 0; i < 3; i++) {
int max = 0;
int val = 0;
for (Map.Entry<Integer, Integer> entry : colorMap.get(i).entrySet()) {
if (entry.getValue() > max) {
max = entry.getValue();
val = entry.getKey();
}
}
rgb[i] = val;
}
int dominantColor = Color.rgb(rgb[0], rgb[1], rgb[2]);
return dominantColor;
}
方法2(舊法)
ARGB_4444
色彩空間計算每種顏色的出現,並找到最大的一個作爲主色
public int getDominantColor2(Bitmap bitmap) {
if (bitmap == null)
throw new NullPointerException();
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int size = width * height;
int pixels[] = new int[size];
Bitmap bitmap2 = bitmap.copy(Bitmap.Config.ARGB_4444, false);
bitmap2.getPixels(pixels, 0, width, 0, 0, width, height);
HashMap<Integer, Integer> colorMap = new HashMap<Integer, Integer>();
int color = 0;
Integer count = 0;
for (int i = 0; i < pixels.length; i++) {
color = pixels[i];
count = colorMap.get(color);
if (count == null)
count = 0;
colorMap.put(color, ++count);
}
int dominantColor = 0;
int max = 0;
for (Map.Entry<Integer, Integer> entry : colorMap.entrySet()) {
if (entry.getValue() > max) {
max = entry.getValue();
dominantColor = entry.getKey();
}
}
return dominantColor;
}
問題:什麼是bitmap2?從原始位圖複製後,您似乎沒有使用它。 –
還有一個另一種解決方案,它更近似的,但如果你不希望有用於搜索的顏色長時間的延遲,它可以做的工作。
public static int getDominantColor(Bitmap bitmap) {
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, 1, 1, true);
final int color = newBitmap.getPixel(0, 0);
newBitmap.recycle();
return color;
}
這是一個非常有用的答案。我正在使用循環方法,但這是使用戶界面生澀。現在非常流暢。 –
儘管代碼中存在語法錯誤。 –
從支持:palette-v7:25.0.0開始,這不再需要自定義方法 - 只需使用palette.getDominantSwatch()即可。 –
沒有其他的答案爲我做了這份工作,我也沒有排除問題的原因。
這是我最終使用:用棒棒糖,有助於從位圖中提取突出的顏色加入
public static int getDominantColor(Bitmap bitmap) {
if (bitmap == null) {
return Color.TRANSPARENT;
}
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int size = width * height;
int pixels[] = new int[size];
//Bitmap bitmap2 = bitmap.copy(Bitmap.Config.ARGB_4444, false);
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
int color;
int r = 0;
int g = 0;
int b = 0;
int a;
int count = 0;
for (int i = 0; i < pixels.length; i++) {
color = pixels[i];
a = Color.alpha(color);
if (a > 0) {
r += Color.red(color);
g += Color.green(color);
b += Color.blue(color);
count++;
}
}
r /= count;
g /= count;
b /= count;
r = (r << 16) & 0x00FF0000;
g = (g << 8) & 0x0000FF00;
b = b & 0x000000FF;
color = 0xFF000000 | r | g | b;
return color;
}
一個新的API。有關詳細信息,請參見[我的答案](http://stackoverflow.com/a/28145358/1956632)。由於提到的Palette類位於support7庫中,因此它應該可以在舊版本的Android中使用。 –
安卓v7調色板支持庫爲我們做。所有尋找演示http://code2concept.blogspot.in/2015/10/android-support-v7-palette-demo.html – nitesh