由于公司目前是做智能音乐灯的,由于控灯需要绘制了各种各样的取色器,现在可以已一个老司机的身份来分析一下HSV的取色盘。
HSV模型了解
它是一个倒锥子模型,这个模型就是按色彩、深浅、明暗来描述的。
- H是色彩,范围0° ~ 360°,红(0°)、绿(120°)、蓝(240°);
- S是深浅, S = 0时,只有灰度,越往圆心的位置越偏白;
- V是明暗,表示色彩的明亮程度,越往锥子的顶点越偏黑(v = max(r, g, b))。
由RGB到HSV的转换:
图像渲染(Shader)
在Android中,提供了Shader类专门用来渲染图像以及一些几何图形。
Shader类包括了5个直接子类,分别为:BitmapShader、ComposeShader、LinearGradient、RadialGradient以及SweepGradient。其中,BitmapShader用于图像渲染;ComposeShader用于混合渲染;LinearGradient用于线性渲染;RadialGradient用于环形渲染;而SweepGradient则用于梯度渲染。显示效果如下图:
色盘源码:
public class ColorPicker extends View {
private static final float RADIUS_WIDTH_RATIO = 0.42f;
private Paint mPaint;
private Paint colorWheelPaint; // 绘制色盘
private Bitmap colorWheelBitmap; // 彩灯位图
private int centerX, centerY;
private int colorWheelRadius;
private Rect mColorWheelRect;
public ColorPicker(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setAlpha(100);
colorWheelPaint = new Paint();
colorWheelPaint.setAntiAlias(true);//消除锯齿
colorWheelPaint.setDither(true);//防抖动
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(colorWheelBitmap, mColorWheelRect.left, mColorWheelRect.top, null);
}
@Override
protected void onSizeChanged(int width, int height, int oldw, int oldh) {
centerX = width / 2;
centerY = height / 2;
colorWheelRadius = (int) (width * RADIUS_WIDTH_RATIO);
mColorWheelRect = new Rect(centerX - colorWheelRadius, centerY - colorWheelRadius, centerX + colorWheelRadius, centerY + colorWheelRadius);
colorWheelBitmap = createColorWheelBitmap(colorWheelRadius * 2, colorWheelRadius * 2);
}
private Bitmap createColorWheelBitmap(int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
int colorCount = 12;
int colorAngleStep = 360 / 12;
int colors[] = new int[colorCount + 1];
float hsv[] = new float[] { 0f, 1f, 1f };
for (int i = 0; i < colors.length; i++) {
hsv[0] = 360 - (i * colorAngleStep) % 360;
colors[i] = Color.HSVToColor(hsv);
}
colors[colorCount] = colors[0];
SweepGradient sweepGradient = new SweepGradient(width / 2, height / 2, colors, null);
RadialGradient radialGradient = new RadialGradient(width / 2, height / 2, colorWheelRadius, 0xFFFFFFFF, 0x00FFFFFF, TileMode.CLAMP);
ComposeShader composeShader = new ComposeShader(sweepGradient, radialGradient, PorterDuff.Mode.SRC_OVER);
colorWheelPaint.setShader(composeShader);
Canvas canvas = new Canvas(bitmap);
canvas.drawCircle(width / 2, height / 2, colorWheelRadius, colorWheelPaint);
return bitmap;
}
}
效果图:
更多关于取色盘的资料和源码,请点此:
https://github.com/RuiRay/MyAndroidDemo