mirror of
https://github.com/nextcloud/android.git
synced 2024-11-25 14:45:47 +03:00
use same algo for avatar placeholder
This commit is contained in:
parent
620f9db9b5
commit
c7ee4f1a60
2 changed files with 98 additions and 16 deletions
|
@ -113,10 +113,10 @@ public class TextDrawable extends Drawable {
|
|||
@NonNull
|
||||
public static TextDrawable createNamedAvatar(String name, float radiusInDp) throws
|
||||
UnsupportedEncodingException, NoSuchAlgorithmException {
|
||||
int[] rgb = BitmapUtils.calculateRGB(name);
|
||||
TextDrawable avatar = new TextDrawable(
|
||||
name.substring(0, 1).toUpperCase(), rgb[0], rgb[1], rgb[2], radiusInDp);
|
||||
return avatar;
|
||||
int[] hsl = BitmapUtils.calculateHSL(name);
|
||||
int[] rgb = BitmapUtils.HSLtoRGB(hsl[0], hsl[1], hsl[2], 1);
|
||||
|
||||
return new TextDrawable(name.substring(0, 1).toUpperCase(), rgb[0], rgb[1], rgb[2], radiusInDp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,16 +29,17 @@ import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
|
|||
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Utility class with methods for decoding Bitmaps.
|
||||
*/
|
||||
public class BitmapUtils {
|
||||
public static final String TAG = BitmapUtils.class.getSimpleName();
|
||||
|
||||
|
||||
/**
|
||||
|
@ -188,7 +189,7 @@ public class BitmapUtils {
|
|||
*
|
||||
* @param h Hue is specified as degrees in the range 0 - 360.
|
||||
* @param s Saturation is specified as a percentage in the range 1 - 100.
|
||||
* @param l Lumanance is specified as a percentage in the range 1 - 100.
|
||||
* @param l Luminance is specified as a percentage in the range 1 - 100.
|
||||
* @param alpha the alpha value between 0 - 1
|
||||
* adapted from https://svn.codehaus.org/griffon/builders/gfxbuilder/tags/GFXBUILDER_0.2/
|
||||
* gfxbuilder-core/src/main/com/camick/awt/HSLColor.java
|
||||
|
@ -267,17 +268,98 @@ public class BitmapUtils {
|
|||
* @throws UnsupportedEncodingException if the charset is not supported
|
||||
* @throws NoSuchAlgorithmException if the specified algorithm is not available
|
||||
*/
|
||||
public static int[] calculateRGB(String name) throws UnsupportedEncodingException, NoSuchAlgorithmException {
|
||||
// using adapted algorithm from /core/js/placeholder.js:50
|
||||
byte[] seed = name.getBytes("UTF-8");
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
Integer seedMd5Int = String.format(Locale.ROOT, "%032x",
|
||||
new BigInteger(1, md.digest(seed))).hashCode();
|
||||
public static int[] calculateHSL(String name) throws UnsupportedEncodingException, NoSuchAlgorithmException {
|
||||
// using adapted algorithm from https://github.com/nextcloud/server/blob/master/core/js/placeholder.js#L126
|
||||
|
||||
double maxRange = Integer.MAX_VALUE;
|
||||
float hue = (float) (seedMd5Int / maxRange * 360);
|
||||
String[] result = new String[]{"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"};
|
||||
double[] rgb = new double[]{0, 0, 0};
|
||||
int sat = 70;
|
||||
int lum = 68;
|
||||
int modulo = 16;
|
||||
|
||||
return BitmapUtils.HSLtoRGB(hue, 90.0f, 65.0f, 1.0f);
|
||||
String hash = name.toLowerCase().replaceAll("[^0-9a-f]", "");
|
||||
|
||||
if (!hash.matches("^[0-9a-f]{32}")) {
|
||||
hash = md5(hash);
|
||||
}
|
||||
|
||||
// Splitting evenly the string
|
||||
for (int i = 0; i < hash.length(); i++) {
|
||||
result[i % modulo] = result[i % modulo] + String.valueOf(Integer.parseInt(hash.substring(i, i + 1), 16));
|
||||
}
|
||||
|
||||
// Converting our data into a usable rgb format
|
||||
// Start at 1 because 16%3=1 but 15%3=0 and makes the repartition even
|
||||
for (int count = 1; count < modulo; count++) {
|
||||
rgb[count % 3] += (Integer.parseInt(result[count]));
|
||||
}
|
||||
|
||||
// Reduce values bigger than rgb requirements
|
||||
rgb[0] = rgb[0] % 255;
|
||||
rgb[1] = rgb[1] % 255;
|
||||
rgb[2] = rgb[2] % 255;
|
||||
|
||||
double[] hsl = rgbToHsl(rgb[0], rgb[1], rgb[2]);
|
||||
|
||||
// Classic formula to check the brightness for our eye
|
||||
// If too bright, lower the sat
|
||||
double bright = Math.sqrt(0.299 * Math.pow(rgb[0], 2) + 0.587 * Math.pow(rgb[1], 2) + 0.114
|
||||
* Math.pow(rgb[2], 2));
|
||||
|
||||
if (bright >= 200) {
|
||||
sat = 60;
|
||||
}
|
||||
|
||||
return new int[]{(int) (hsl[0] * 360), sat, lum};
|
||||
}
|
||||
|
||||
private static double[] rgbToHsl(double r, double g, double b) {
|
||||
r /= 255;
|
||||
g /= 255;
|
||||
b /= 255;
|
||||
|
||||
double max = Math.max(r, Math.max(g, b));
|
||||
double min = Math.min(r, Math.min(g, b));
|
||||
double h = (max + min) / 2;
|
||||
double s;
|
||||
double l = (max + min) / 2;
|
||||
|
||||
if (max == min) {
|
||||
h = s = 0; // achromatic
|
||||
} else {
|
||||
double d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
|
||||
if (max == r) {
|
||||
h = (g - b) / d + (g < b ? 6 : 0);
|
||||
} else if (max == g) {
|
||||
h = (b - r) / d + 2;
|
||||
} else if (max == b) {
|
||||
h = (r - g) / d + 4;
|
||||
}
|
||||
h /= 6;
|
||||
}
|
||||
|
||||
double[] hsl = new double[]{0.0, 0.0, 0.0};
|
||||
hsl[0] = h;
|
||||
hsl[1] = s;
|
||||
hsl[2] = l;
|
||||
|
||||
return hsl;
|
||||
}
|
||||
|
||||
public static String md5(String string) {
|
||||
try {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.update(string.getBytes());
|
||||
|
||||
return new String(Hex.encodeHex(md5.digest()));
|
||||
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, e.getMessage());
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue