Android編程實(shí)現(xiàn)扭曲圖像的繪制功能示例
本文實(shí)例講述了Android編程實(shí)現(xiàn)扭曲圖像的繪制功能。分享給大家供大家參考,具體如下:
為了實(shí)現(xiàn)動(dòng)畫效果,使用drawBitmapMess方法對(duì)圖像進(jìn)行扭曲,使用定時(shí)器以100毫秒的頻率按圓形軌跡扭曲圖像。
扭曲的關(guān)鍵是生成verts數(shù)組。本例一開始會(huì)先生成verts數(shù)組的初始值:有一定水平和垂直間距的網(wǎng)點(diǎn)坐標(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(); // 計(jì)算圖形中心點(diǎn)坐標(biāo) int centerX = bitmap.getWidth() / 2; int centerY = bitmap.getHeight() / 2; double radian = Math.toRadians((double) angle); // 通過圓心坐標(biāo)、半徑和當(dāng)前角度計(jì)算當(dāng)前圓周的某點(diǎn)橫坐標(biāo) int currentX = (int) (centerX + 100 * Math.cos(radian)); // 通過圓心坐標(biāo)、半徑和當(dāng)前角度計(jì)算當(dāng)前圓周的某點(diǎn)縱坐標(biāo) int currentY = (int) (centerY + 100 * Math.sin(radian)); // 重繪View,并在圓周的某一點(diǎn)扭曲圖像 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ù)組的初始值,這兩個(gè)數(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)前扭曲的點(diǎn)(扭曲區(qū)域的中心點(diǎn)),也就是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(); // 開始定時(shí)器 timer.schedule(timerTask, 0, 100); }
下面來看看扭曲后的效果,不同時(shí)刻,圖片呈現(xiàn)出不同的扭曲效果:
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android圖形與圖像處理技巧總結(jié)》、《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- Android編程之canvas繪制各種圖形(點(diǎn),直線,弧,圓,橢圓,文字,矩形,多邊形,曲線,圓角矩形)
- Android開發(fā)之OpenGL繪制2D圖形的方法分析
- Android編程繪圖操作之弧形繪制方法示例
- Android繪制圓形百分比加載圈效果
- Android shape 繪制圖形的實(shí)例詳解
- Android中使用ListView繪制自定義表格技巧分享
- Android使用音頻信息繪制動(dòng)態(tài)波紋
- Android開發(fā) OpenGL ES繪制3D 圖形實(shí)例詳解
- Android編程繪制圓形圖片的方法
- 解決Android SurfaceView繪制觸摸軌跡閃爍問題的方法
- Android自定義View之繼承TextView繪制背景
- Android開發(fā)之繪制平面上的多邊形功能分析
相關(guān)文章
小心!Listview結(jié)合EditText使用實(shí)例中遇到的那些坑
小心!Listview結(jié)合EditText使用實(shí)例中遇到的那些坑,解決EditText焦點(diǎn)丟失、保存數(shù)據(jù)以及滾動(dòng)沖突的問題,感興趣的小伙伴們可以參考一下2016-06-06Android實(shí)現(xiàn)史上最簡單自定義開關(guān)按鈕的方法
在平常的開發(fā)中按鈕是經(jīng)常使用到的控件之一,下面這篇文章主要給大家介紹了關(guān)于Android實(shí)現(xiàn)史上最簡單自定義開關(guān)按鈕的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04Android實(shí)現(xiàn)點(diǎn)擊縮略圖放大效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)點(diǎn)擊縮略圖放大效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09Android GZip的使用-開發(fā)中網(wǎng)絡(luò)請(qǐng)求的壓縮實(shí)例詳解
這篇文章主要介紹了Android GZip的使用-開發(fā)中網(wǎng)絡(luò)請(qǐng)求的壓縮實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2016-11-11Android Studio 自定義Debug變量視圖的方法
這篇文章主要介紹了Android Studio 自定義Debug變量視圖的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07Android Studio 3.x版本 的輸入法遇到的坑及解決方案
前些天把AndroidStudio從2.3.3升級(jí)到3.0,遇到了不少坑,其中一個(gè)巨坑就是輸入中文不提示的問題,下面給大家分享Android Studio 3.x版本的輸入法遇到的坑及解決方案,一起看看吧2017-11-11Android App實(shí)現(xiàn)監(jiān)聽軟鍵盤按鍵的三種方式
本篇文章主要介紹Android App實(shí)現(xiàn)監(jiān)聽軟鍵盤按鍵的三種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03