在本周,我和其他小组成员一起讨论了字体变形的实现方法。本来的设想是构造个人字体库,但是通过在网上查阅相关资料进行初步了解后发现该方法难以实现,因为我们难以对所有的情况生成变形字体。所以我们最后决定通过在Android的canvas上通过绘制来存储个人字体并针对不同操作进行基本变形。我负责并完成的工作包括画板的绘制、字体的加粗、倾斜、抖动。
1.画板的实现
private View.OnClickListener click = new OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_thick:
if (showBitmap == null) {
showBitmap = Bitmap.createBitmap(iv_canvas.getWidth(),
iv_canvas.getHeight(), Bitmap.Config.ARGB_8888);
show_canvas = new Canvas(showBitmap);
show_canvas.drawColor(Color.WHITE);
}
int[][] temppixel = saveBitmapArray(baseBitmap);
paintNewImage(temppixel, temppixel.length, temppixel[0].length);
//savePicture(baseBitmap, "test.jpg");
break;
case R.id.btn_resume:
resumeCanvas();
break;
case R.id.btn_incline:
if (showBitmap == null) {
showBitmap = Bitmap.createBitmap(iv_canvas.getWidth(),
iv_canvas.getHeight(), Bitmap.Config.ARGB_8888);
show_canvas = new Canvas(showBitmap);
show_canvas.drawColor(Color.WHITE);
}
int[][] temppixe2 = saveBitmapArray(baseBitmap);
skewImage(temppixe2, temppixe2.length, temppixe2[0].length);
//show_canvas.restore();
break;
case R.id.btn_tremble:
showBitmap = Bitmap.createBitmap(iv_canvas.getWidth(),
iv_canvas.getHeight(), Bitmap.Config.ARGB_8888);
show_canvas = new Canvas(showBitmap);
int[][] temppixe3 = saveBitmapArray(baseBitmap);
trembleImage(showBitmap,temppixe3,temppixe3.length,temppixe3[0].length);
break;
case R.id.btn_distort:
showBitmap = Bitmap.createBitmap(iv_canvas.getWidth(),
iv_canvas.getHeight(), Bitmap.Config.ARGB_8888);
showBitmap = baseBitmap;
show_canvas = new Canvas(showBitmap);
new_canvas.setImageBitmap(showBitmap);
break;
default:
break;
}
}
};
2.将创建的字体存储成矩阵
protected int[][] saveBitmapArray(Bitmap bmp) {
int width = bmp.getWidth();
int height = bmp.getHeight();
//bmp.getPixels(pixels,0,width,0,0,width,height);
int[][] ps = new int[height][width];//存成一个长*宽的矩阵
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int p = bmp.getPixel(j, i);//p是-1是白色,p是-16777216是黑色
if (p == -1)
ps[i][j] = 1;
else
ps[i][j] = 0;
}
}
return ps;
}
3.字体的加粗、倾斜、抖动
/*
* 根据二维数组的值绘制加粗新图像*/
protected void paintNewImage(int[][] arr, int row, int col) {//二维数组的行数和列数
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
paint.setARGB(255, 0, 0, 0);
paint.setStrokeWidth(10);
if (arr[i][j] == 0)
show_canvas.drawPoint(j, i, paint);
}
}
paint.setStrokeWidth(5f);
// 把图片展示到ImageView中
new_canvas.setImageBitmap(showBitmap);
}
/*
* 绘制倾斜图像*/
protected void skewImage(int[][] arr, int row, int col) {//二维数组的行数和列数
paint.setStrokeWidth(0f);
show_canvas.skew(0.5f,0);
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
paint.setARGB(255, 0, 0, 0);
if (arr[i][j] == 0)
show_canvas.drawPoint(j, i, paint);
}
}
//paint.setStrokeWidth(3f);
//show_canvas.save();
// 把图片展示到ImageView中
new_canvas.setImageBitmap(showBitmap);
//show_canvas.restore();
paint.setStrokeWidth(5f);
}
/*
* 绘制抖动图像
*/
protected void trembleImage(Bitmap bmp,int[][] arr, int row, int col){
int width = 35;//几行为一组
int height = 35;//几列为一组
int half_width = 18;
int half_height = 18;
int row_block = row/width;//行被分成了几组
int col_block = col/height;//列被分成了几组
int[][] new_arr = arr;
int tense = 3;//抖动程度(1-5),数值越小抖得越厉害
for(int i = 0;i < row_block;i++)
{
for(int j = 0;j < height;j++)
{
for(int k = 0;k < col;k++) {
if(k<col - half_height)
if (j < half_height)
new_arr[j + i * height][k] = arr[j + i * height][k + (int)j/tense];
else
new_arr[j + i * height][k] = arr[j + i * height][k - (int)j/tense + height/tense];
else
new_arr[j + i * height][k] = arr[j + i * height][k];
}
}
}
for(int i = 0;i < col_block;i++)
{
for(int j = 0;j < width;j++)
{
for(int k = 0;k < row;k++) {
if(k<row - half_width)
if (j < half_width)
new_arr[k][j + i * width] = arr[k + (int)j/tense][j + i * width];
else
new_arr[k][j + i * width] = arr[k - (int)j/tense + width/tense][j + i * width];
else
new_arr[k][j + i * width] = arr[k][j + i * width];
}
}
}
paint.setStrokeWidth(0f);
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
paint.setARGB(255, 0, 0, 0);
if (new_arr[i][j] == 0)
show_canvas.drawPoint(j, i, paint);
}
}
// 把图片展示到ImageView中
new_canvas.setImageBitmap(bmp);
//show_canvas.restore();
paint.setStrokeWidth(5f);
}
简单的效果图:加粗、倾斜、抖动,其中变形程度是可以通过传入参数改变的,未来会将手机传感器的参数传入其中。