接下来通过手机的加速度计获得了手机的抖动程度,重力传感器获得了手机的偏向,通过按下和抬起的时间差记录触键时间,通过传入随机数在每次输出时对原始字符图片进行一些随机偏移。这些作用效果叠加起来构成了输出效果。
SensorEventListener sensorListener = new SensorEventListener() {
//传感器改变时,一般是通过这个方法里面的参数确定传感器状态的改变
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
{
accelerometerValues = sensorEvent.values.clone();
float[] values = sensorEvent.values;//获取传感器的数据
//float max = sensor.getMaximumRange();//获取最大值范围
if (values.length >= 3) {
float x = values[0];//右侧面向上时为g(9.8)
float y = values[1];//上侧面向上时为g(9.8)
float z = values[2];
//抖动
float xx = values[0] - usedValues[0];
float yy = values[1] - usedValues[1];
float zz = values[2] - usedValues[2];
float Tense = Math.abs(xx)+Math.abs(yy)+Math.abs(zz);
usedValues[0] = x;
usedValues[1] = y;
usedValues[2] = z;
if(Tense >=15)
tempTense = 1;
else if(Tense >=6&&Tense < 15)
tempTense = 2;
else if(Tense>=4&&Tense < 6)
tempTense = 3;
else if(Tense >=2&&Tense<4)
tempTense = 4;
else if(Tense>=1&&Tense<2)
tempTense = 5;
else
tempTense = 10;
//倾斜
float angle;
if(y>0)
{
angle = x*8;
if(angle>25)
angle = 25;
}
else
angle = 0;
numboardUtil.getSkewData(angle);
}
numboardUtil.getSensorData(tempTense);
}else if (sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
}
}
/*获得触键时间*/
class touchKeyListener implements View.OnTouchListener{
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN://按键的时间
Calendar calendar = Calendar.getInstance();
int SS = calendar.get(Calendar.SECOND);
int MI = calendar.get(Calendar.MILLISECOND);
second1 = SS;
millisecond1 = MI;
break;
case MotionEvent.ACTION_UP://抬起的时间
Calendar c = Calendar.getInstance();
int S = c.get(Calendar.SECOND);
int mi = c.get(Calendar.MILLISECOND);
second2 = S;
millisecond2 = mi;
totalMilliSecond = (second2-second1)*1000+millisecond2-millisecond1;//时间差,以毫秒计
int thick;
if(totalMilliSecond<20)
thick = 0;
else if(totalMilliSecond>=20&&totalMilliSecond<80)
thick = 1;
else if (totalMilliSecond>=80&&totalMilliSecond<150)
thick = 3;
else if(totalMilliSecond>=150&&totalMilliSecond<300)
thick = 5;
else if(totalMilliSecond>=300&&totalMilliSecond<600)
thick = 7;
else if(totalMilliSecond>=600&&totalMilliSecond<800)
thick = 8;
else if(totalMilliSecond>=800&&totalMilliSecond<1000)
thick = 9;
else thick = 10;
numboardUtil.getTouchTime(thick);
break;
case MotionEvent.ACTION_MOVE:
break;
default:
break;
}
return false;
}
}
在按键的同时进行反应当前形态的字符绘制,其中的具体变形方法时在之前的工作中完成过的,这里将传感器获得的数据加工后作为参数传入。
protected Bitmap paintNewImage(int[][] arr,float tense,int level,float angle) {//抖动程度、画笔粗细、倾斜角度
int row = arr.length;
int col = arr[0].length;
int min=0;
int max=30;
Random random = new Random();
int num1 = random.nextInt(max)%(max-min+1) -15;
int num2 = random.nextInt(max)%(max-min+1) -15;
int[][] arr1 = distort1(arr,num1,num2,row,col);//异形文字
arr = trembleImage(arr1,tense);//抖动
paint = new Paint();
//if (showBitmap == null) {
//}
int left = 0,right = 0;
boolean flag = true;
//判断最左和最右的像素,对图片进行一个裁剪
for(int i = 0;i<col&&flag;i++)
{
for(int j = 0;j<row;j++)
{
if(arr[j][i] == 0&&j<0.95*row)
{
left = i;
flag = false;
break;
}
}
}
flag = true;
for(int i = col-1;i>0&&flag;i--)
{
for(int j = 0;j<row;j++)
{
if(arr[j][i] == 0&&j<0.95*row)
{
right = i;
flag = false;
break;
}
}
}
showBitmap = Bitmap.createBitmap(right - left +15,
MY_ROW, Bitmap.Config.ARGB_8888);
show_canvas = new Canvas(showBitmap);
show_canvas.drawColor(Color.WHITE);
show_canvas.skew((float)Math.tan(angle*3.14/180),0f);
show_canvas.translate(-50*(float)Math.tan(angle*3.14/180),0);
for (int i = 0; i < row; i++) {
for (int j = left; j < right; j++) {
paint.setARGB(255, 0, 0, 0);
paint.setStrokeWidth(level);
if (arr[i][j] == 0&&i<0.95*row)
show_canvas.drawPoint(j-left+8, i, paint);
}
}
return showBitmap;
}
在语音识别的功能中也将自定义键盘状态下的文本以个性化字体的形式表现出来
@Override
public void onResult(RecognizerResult results, boolean isLast) {
//Log.L(results.getResultString());
System.out.println("间断结果——————————————————————————————————");
printResult(results);
if(isLast){
//因为是last,所以new_piece稳定到了最终结果,不再变化。
result_string+=new_piece;
//针对不同的文本显示方式,系统字体,手写个性化字体
String tag=mChangeModeLayout.getTag().toString();
switch (tag){
case "1":
//系统字体
mEtInput.setText(result_string);
break;
case "2":
//手写个性化字体
//音量
sound=sound/soundCount;
showTip("平均音量"+sound);
if(sound<=18){
sound=2;
}else{
sound=sound/3;
}
for(int i=0;i<new_piece.length();i++){
int start=mEtInput.getSelectionStart();
char singleLetter=new_piece.charAt(i);
int pos=singleLetter-33;
Bitmap bmp;
if(pos==-1){
//空格键
bmp = Bitmap.createBitmap(MY_COL/2,MY_ROW, Bitmap.Config.ARGB_8888);//空白图片
}else if(myImageArrays[pos]!=null){
bmp = paintNewImage(myImageArrays[pos],10,sound,0);
}else{
bmp = Bitmap.createBitmap(MY_COL/2,MY_ROW, Bitmap.Config.ARGB_8888);//空白图片
showTip("个人字体库不完整!");
}
SpannableString ss=getBitmapMime1(bmp);
insertPhotoToEditText(ss);
count++;
inputBmpList.add(start,bmp);
}
sound=0;
soundCount=0;
break;
default:
break;
}
}
}
键盘的输出效果可以看出手机的左右偏向、按键时间以及抖动程度,同时同一字母的两次绘制不会完全相同,符合书写现实。