android仿区块链头像自动生成

总的来说就是输入任何的文字字符,通过一定的算法,然后转成一些乱七八糟的,而且对称的图片。这大概就是那些区块链app的头像吧。

先来看下头像的效果图

头像的构成示意图

android仿区块链头像自动生成_第1张图片
如上图所示,整体的头像分为三个部分,中心,side,角,其中每个部分都是有不同的图形”组成,一个中心,4个side,4个角。每个部分都是从基础图形库中随机读取出来,再设置不同的图片颜色;白色(0xffffff)和一个随机颜色作为这个图形的背景或者图案的颜色,下面我们分别来介绍每个部分的构成

中心

在中心位置画出中心图形。按照一定的规则从基础图形”库中“随机”选取(随机规则后文会有详细的介绍)一个图形,在对图形中的图案进行上色处理(颜色也是随机获取)

######中心图形选取方法

public int	getMiddle(){
	     return positiveMod(value>>2,34) ;//其中value为伪随机数后文有介绍 34为图形库的总数量
	}

其中positiveMode的具体算法为

	public static int positiveMod(long i, int m) {
		return Math.abs((int) (i % m));
	}
	//后文都用 positiveMod()这个方法代替

######中心画笔颜色选取规则

		int r = 100 + mIdenticonHash.getR() * 8;
		int g = 100 + mIdenticonHash.getG() * 8;
		int b = 100 + mIdenticonHash.getB() * 8;

		return 0xff000000 + r * 0x10000 + g * 0x100 + b;
 
     getR() : positiveMod((value >> 16),16);
     getG():  positiveMod((value >> 20),16);
     getB():   positiveMod((value >> 24),16);

######中心画图案的画笔,与画背景的画笔选取规则二选一

		boolean invert = mIdenticonHash.getInvertMiddle() == 0; 
		Paint fg = invert ? mFgPaint : mBgPaint; // true 取第一个
		Paint bg = invert ? mBgPaint : mFgPaint; // true 取第一个
//画背景的画笔,与画图形颜色的画笔随机选一个

	public int getInvertMiddle(){
		return positiveMod((value >> 13),2);
	}

 
		

######主要绘制“中心”代码

private void drawMiddle(Canvas canvas) {
        //随机画的颜色为生成的还是白色
		boolean invert = mIdenticonHash.getInvertMiddle() == 0; // 去的某个值为0

		Paint fg = invert ? mFgPaint : mBgPaint; // true 取第一个
		Paint bg = invert ? mBgPaint : mFgPaint; // true 取第一个

		canvas.save();
		canvas.translate(mTileMeasure.width, mTileMeasure.height); //画布平移 移到中间的的位置,即左上角在中心,通过传入的mTitleMeasure为一个小正方形
		getTile(mIdenticonHash.getMiddle()).draw(canvas, mTileMeasure, 0, bg, fg);
		canvas.restore();

	}

side部分

先从最左边(0,height/3)的部分开始画出第一个图形;第二个side图形开始绕着自身中心点先旋转90度,在移动到(width/3,height/2);第三个side图形也绕着自身中心点旋转90度(相对第一个side图形旋转180度),再移动到(2/3*width,height/3);第四个图形也绕着自身旋转90度(相对第一个side图形旋转270度),再移动到(width/3,0);

######背景画笔,图形的选取上和上面“中心”的选取规则是一样的,只是选取的算法不一样

	boolean invert = mIdenticonHash.getInvertSides() == 0;
	Paint fg = invert ? mFgPaint : mBgPaint;
	Paint bg = invert ? mBgPaint : mFgPaint;
	
	public int getInvertCorners(){
		return positiveMod((value >> 15),2);
	}

######图片选取规则

	public int getSides(){
		return positiveMod((value >> 8),34);
	}

######颜色的选取规则:

	protected int getColorSide(){
		int r = 100 + mIdenticonHash.getG() * 8; 
		int g = 100 + mIdenticonHash.getR() * 8;
		int b = 100 + mIdenticonHash.getB() * 8;

		return 0xff000000 + r * 0x10000 + g * 0x100 + b;
	}
//具体的getG() ,getR(),getB()与“中心”的选取规则相同

######side 初始图片旋转的角度选取:

int rotation = mIdenticonHash.getSidesRotation() * 90; //初始旋转角度选取

public int getSidesRotation(){
	return positiveMod((value >> 30), 4);
}

######主要绘制“side”代码

/**
	 * 旋转画四个边的图形(逆时针)
	 * @param canvas
	 */
	private void drawSides(Canvas canvas) {
		mFgPaint.setColor(getColorSide());

		ClassicIdenticonTile.Tiles drawer = getTile(mIdenticonHash.getSides());

		boolean invert = mIdenticonHash.getInvertSides() == 0;
		int rotation = mIdenticonHash.getSidesRotation() * 90; // 0 1 2 3 *90  只会出现一次

		Paint fg = invert ? mFgPaint : mBgPaint;
		Paint bg = invert ? mBgPaint : mFgPaint;

		canvas.save();
		canvas.translate(0, mTileMeasure.height);
		drawer.draw(canvas, mTileMeasure, 0 + rotation, bg, fg);
		canvas.restore();

		canvas.save();
		canvas.translate(mTileMeasure.width, mTileMeasure.height2);
		drawer.draw(canvas, mTileMeasure, 90 + rotation, bg, fg);
		canvas.restore();

		canvas.save();
		canvas.translate(mTileMeasure.width2, mTileMeasure.height);
		drawer.draw(canvas, mTileMeasure, 180 + rotation, bg, fg);
		canvas.restore();

		canvas.save();
		canvas.translate(mTileMeasure.width, 0);
		drawer.draw(canvas, mTileMeasure, 270 + rotation, bg, fg);
		canvas.restore();

	}

角 部分

先从最左边(0,0)的部分开始画出第一个图形;第二个side图形开始绕着自身中心点先旋转90度,在移动到(0,height);第三个side图形也绕着自身中心点旋转90度(相对第一个side图形旋转180度),再移动到(width,height);第四个图形也绕着自身旋转90度(相对第一个side图形旋转270度),再移动到(width,0);

背景画笔,图形的选取和上面的“中心”,“side”的选取规则是一样的,只是选取的规则不一样

######画笔的选取规则

	boolean invert = mIdenticonHash.getInvertCorners() == 0;
    Paint fg = invert ? mFgPaint : mBgPaint;
	Paint bg = invert ? mBgPaint : mFgPaint;
	
	public int getInvertCorners(){
		return positiveMod((value >> 14),2);
	}

######图形选取规则

public int getCorners(){
	retrun positiveMod((value >> 3), 34);
}

######颜色的选取规则:

	protected int getColorConner(){
		int r = 100 + mIdenticonHash.getB() * 8;
		int g = 100 + mIdenticonHash.getR() * 8;
		int b = 100 + mIdenticonHash.getG() * 8;

		return 0xff000000 + r * 0x10000 + g * 0x100 + b;
	}
//具体的getG() ,getR(),getB()与“中心”,“side”的选取规则相同

######“角” 初始图片旋转的角度选取:

int rotation = mIdenticonHash.getCornersRotation() * 90; //初始旋转角度选取

public int getCornersRotation(){
	return positiveMod((value >> 28), 4);
}

######主要绘制“角”代码

/**
	 /**
	 * 旋转着画四个边角
	 * @param canvas
	 */
	private void drawCorners(Canvas canvas) {
        mFgPaint.setColor(getColorConner());
		ClassicIdenticonTile.Tiles drawer = getTile(mIdenticonHash.getCorners());

		boolean invert = mIdenticonHash.getInvertCorners() == 0;
		int rotation = mIdenticonHash.getCornersRotation() * 90;

		Paint fg = invert ? mFgPaint : mBgPaint;
		Paint bg = invert ? mBgPaint : mFgPaint;

		drawer.draw(canvas, mTileMeasure, 0 + rotation, bg, fg);

		canvas.save();
		canvas.translate(mTileMeasure.width2, 0);
		drawer.draw(canvas, mTileMeasure, 90 + rotation, bg, fg);
		canvas.restore();

		canvas.save();
		canvas.translate(mTileMeasure.width2, mTileMeasure.height2);
		drawer.draw(canvas, mTileMeasure, 180 + rotation, bg, fg);
		canvas.restore();

		canvas.save();
		canvas.translate(0, mTileMeasure.height2);
		drawer.draw(canvas, mTileMeasure, 270 + rotation, bg, fg);
		canvas.restore();
	}
	}

#####补充:
#####伪随机数算法,即前面文字提到的value这个值

 /**
     * 生成一个伪随机数,整个图形的生成都依据这个随机数
     * @param data
     * @return
     */
    public static int FNVHash1(String data)
    {
        final int p = 16777619;
        int hash = (int)2166136261L;
        for(int i=0;i> 7;
        hash += hash << 3; 
        hash ^= hash >> 17;
        hash += hash << 5;
        return hash;
    }
  
    

#####基础图形库
这个没什么好说的就是画一些基础图形。一般来说话的图形越多,真个头像的组合就会越丰富。

总结

其实整个随机头像也是由基础的图形,通过绘制不同的颜色,不同的位置,不同的角度组成的,
也很简单。虽然和其他的效果图有一定的不同,但是总的来说还是实现了这个功能,后续还有很多可以改进的地方。

下载地址: demo下载地址,很久以前写的,如果有需要,下载下来凑合着看吧;

你可能感兴趣的:(android仿区块链头像自动生成)