Android編程實現(xiàn)扭曲圖像的繪制功能示例
本文實例講述了Android編程實現(xiàn)扭曲圖像的繪制功能。分享給大家供大家參考,具體如下:
為了實現(xiàn)動畫效果,使用drawBitmapMess方法對圖像進行扭曲,使用定時器以100毫秒的頻率按圓形軌跡扭曲圖像。
扭曲的關(guān)鍵是生成verts數(shù)組。本例一開始會先生成verts數(shù)組的初始值:有一定水平和垂直間距的網(wǎng)點坐標(biāo)。然后通過warp方法按一定的數(shù)學(xué)方法變化verts數(shù)組中的坐標(biāo)。關(guān)鍵部分的代碼如下:
定義基本變量:MyView是用于顯示扭曲的圖像的自定義view,angle是圓形軌跡的當(dāng)前角度:
private static Bitmap bitmap;
private MyView myView;
private int angle = 0; // 圓形軌跡當(dāng)前的角度
private Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
switch (msg.what)
{
case 1:
Random random = new Random();
// 計算圖形中心點坐標(biāo)
int centerX = bitmap.getWidth() / 2;
int centerY = bitmap.getHeight() / 2;
double radian = Math.toRadians((double) angle);
// 通過圓心坐標(biāo)、半徑和當(dāng)前角度計算當(dāng)前圓周的某點橫坐標(biāo)
int currentX = (int) (centerX + 100 * Math.cos(radian));
// 通過圓心坐標(biāo)、半徑和當(dāng)前角度計算當(dāng)前圓周的某點縱坐標(biāo)
int currentY = (int) (centerY + 100 * Math.sin(radian));
// 重繪View,并在圓周的某一點扭曲圖像
myView.mess(currentX, currentY);
angle += 2;
if (angle > 360)
angle = 0;
break;
}
super.handleMessage(msg);
}
};
private TimerTask timerTask = new TimerTask()
{
public void run()
{
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
以下是自定義view,MyView的具體內(nèi)容:
private static class MyView extends View
{
private static final int WIDTH = 20;
private static final int HEIGHT = 20;
private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1);
private final float[] verts = new float[COUNT * 2];
private final float[] orig = new float[COUNT * 2];
private final Matrix matrix = new Matrix();
private final Matrix m = new Matrix();
// 設(shè)置verts數(shù)組的值
private static void setXY(float[] array, int index, float x, float y)
{
array[index * 2 + 0] = x;
array[index * 2 + 1] = y;
}
public MyView(Context context)
{
super(context);
setFocusable(true);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
float w = bitmap.getWidth();
float h = bitmap.getHeight();
int index = 0;
// 生成verts和orig數(shù)組的初始值,這兩個數(shù)組的值是一樣的,只是在扭曲的過程中需要修改verts
// 的值,而修改verts的值要將原始的值保留在orig數(shù)組中
for (int y = 0; y <= HEIGHT; y++)
{
float fy = h * y / HEIGHT;
for (int x = 0; x <= WIDTH; x++)
{
float fx = w * x / WIDTH;
setXY(verts, index, fx, fy);
setXY(orig, index, fx, fy);
index += 1;
}
}
matrix.setTranslate(10, 10);
setBackgroundColor(Color.WHITE);
}
@Override
protected void onDraw(Canvas canvas)
{
canvas.concat(matrix);
canvas.drawBitmapMesh(bitmap, WIDTH, HEIGHT, verts, 0, null, 0,null);
}
// 用于扭曲圖像的方法,在該方法中根據(jù)當(dāng)前扭曲的點(扭曲區(qū)域的中心點),也就是cx和cy參數(shù),
// 來不斷變化verts數(shù)組中的坐標(biāo)值
private void warp(float cx, float cy)
{
final float K = 100000; // 該值越大,扭曲得越嚴(yán)重(扭曲的范圍越大)
float[] src = orig;
float[] dst = verts;
// 按一定的數(shù)學(xué)規(guī)則生成verts數(shù)組中的元素值
for (int i = 0; i < COUNT * 2; i += 2)
{
float x = src[i + 0];
float y = src[i + 1];
float dx = cx - x;
float dy = cy - y;
float dd = dx * dx + dy * dy;
float d = FloatMath.sqrt(dd);
float pull = K / ((float) (dd *d));
if (pull >= 1)
{
dst[i + 0] = cx;
dst[i + 1] = cy;
}
else
{
dst[i + 0] = x + dx * pull;
dst[i + 1] = y + dy * pull;
}
}
}
// 用于MyView外部控制圖像扭曲的方法。該方法在handleMessage方法中被調(diào)用
public void mess(int x, int y)
{
float[] pt ={ x, y };
m.mapPoints(pt);
// 重新生成verts數(shù)組的值
warp(pt[0], pt[1]);
invalidate();
}
}
}
以下是Activity的onCreate方法:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
myView = new MyView(this);
setContentView(myView);
Timer timer = new Timer();
// 開始定時器
timer.schedule(timerTask, 0, 100);
}
下面來看看扭曲后的效果,不同時刻,圖片呈現(xiàn)出不同的扭曲效果:

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android圖形與圖像處理技巧總結(jié)》、《Android開發(fā)入門與進階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對大家Android程序設(shè)計有所幫助。
- Android編程之canvas繪制各種圖形(點,直線,弧,圓,橢圓,文字,矩形,多邊形,曲線,圓角矩形)
- Android開發(fā)之OpenGL繪制2D圖形的方法分析
- Android編程繪圖操作之弧形繪制方法示例
- Android繪制圓形百分比加載圈效果
- Android shape 繪制圖形的實例詳解
- Android中使用ListView繪制自定義表格技巧分享
- Android使用音頻信息繪制動態(tài)波紋
- Android開發(fā) OpenGL ES繪制3D 圖形實例詳解
- Android編程繪制圓形圖片的方法
- 解決Android SurfaceView繪制觸摸軌跡閃爍問題的方法
- Android自定義View之繼承TextView繪制背景
- Android開發(fā)之繪制平面上的多邊形功能分析
相關(guān)文章
小心!Listview結(jié)合EditText使用實例中遇到的那些坑
小心!Listview結(jié)合EditText使用實例中遇到的那些坑,解決EditText焦點丟失、保存數(shù)據(jù)以及滾動沖突的問題,感興趣的小伙伴們可以參考一下2016-06-06
Android實現(xiàn)史上最簡單自定義開關(guān)按鈕的方法
在平常的開發(fā)中按鈕是經(jīng)常使用到的控件之一,下面這篇文章主要給大家介紹了關(guān)于Android實現(xiàn)史上最簡單自定義開關(guān)按鈕的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-04-04
Android GZip的使用-開發(fā)中網(wǎng)絡(luò)請求的壓縮實例詳解
這篇文章主要介紹了Android GZip的使用-開發(fā)中網(wǎng)絡(luò)請求的壓縮實例詳解的相關(guān)資料,需要的朋友可以參考下2016-11-11
Android Studio 自定義Debug變量視圖的方法
這篇文章主要介紹了Android Studio 自定義Debug變量視圖的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
Android Studio 3.x版本 的輸入法遇到的坑及解決方案
前些天把AndroidStudio從2.3.3升級到3.0,遇到了不少坑,其中一個巨坑就是輸入中文不提示的問題,下面給大家分享Android Studio 3.x版本的輸入法遇到的坑及解決方案,一起看看吧2017-11-11
Android App實現(xiàn)監(jiān)聽軟鍵盤按鍵的三種方式
本篇文章主要介紹Android App實現(xiàn)監(jiān)聽軟鍵盤按鍵的三種方式,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03

