A. android中使用canvas.drawText函數可否設置旋轉
使用Paint類的breakText對Text進行分解 然後分別使用Canvas的drawText進行繪制
B. canvas繪制圖線後,無法旋轉,求助
canvas沒有直接旋轉圖片的功能,只能旋轉畫布
一般的做法是
ctx.save();//保存狀態
ctx.translate(200,200);//設置畫布上的(0,0)位置,也就是旋轉的中心點
ctx.rotate(45*Math.PI/180);
ctx.drawImage(img,-img.width/2,-img.height/2);//把圖片繪制在旋轉的中心點,
ctx.restore();//恢復狀態
C. Android繪圖之Canvas變換(6)
前面講解了Canvas的基本概念, Android繪圖之Canvas概念理解(5) ,
對Canvas的概念進行了分析,但是沒有說明和屏幕的關系,Canvas不等於屏幕,屏幕不會動的,我們也無法對屏幕進行(平移,縮放等)操作,只能對Canvas進行操作,所以對Canvas進行操作,屏幕不動,最終會導致看到的圖像不同。
下面開始講解Canvas的變幻操作:
包括:translate,rotate,scale,skew,clip,clipout,matrix
先從最簡單的平移開始:
對Canvas進行平移,
dx: x軸方向進行平移,正值向屏幕右側
dy:y軸方向進行平移,正值向屏幕下方
繪制兩個點查看原點位置。
原點顯然改變了,以後再繪制任何形狀都是以translate後的原點開始繪制。
參數說明
sx:橫向的縮放,默認為1,小數縮小,整數放大
sy:縱向的縮放,默認為1,小數縮小,整數放大
px,py,看源碼知道是先translate,執行sx,sy然後再translate反方向。
第二次translate的坐標為(-px sx,-px sy),最終的效果就是px,py是縮放後不動的點。
縮放後坐標減半。
如果想控制縮放後的位置,如何控制呢,這就需要第二個函數。
還可以控制其他位置,例如控制縮放後在中心。
rotate有兩個函數:
rotate(float degrees)
rotate(float degrees, float px, float py)
Degree:旋轉的角度,正值為順時針,負值為逆時針
Px,py:旋轉的中心,如果不指定旋轉中心默認為(0,0)點
指定旋轉中心為矩形中心
參數說明:
sx:畫布在x方向上傾斜相應的角度,sx傾斜角度的tan值,
sy:畫布在y軸方向上傾斜相應的角度,sy為傾斜角度的tan值,
根據矩形或者路徑裁剪畫布,畫布被切割之後,只有部分區域可用,其他區域無法繪制內容。
Clip函數切割的區域可用,clipOut未被切割的區域可用。(過時函數不再講解)
Matrix提供了一些方法來控制變換:
android繪圖之Paint(1)
android繪圖之Canvas基礎(2)
Android繪圖之Path(3)
Android繪圖之drawText繪制文本相關(4)
Android繪圖之Canvas概念理解(5)
Android繪圖之Canvas變換(6)
Android繪圖之Canvas狀態保存和恢復(7)
Android繪圖之PathEffect (8)
Android繪圖之LinearGradient線性漸變(9)
Android繪圖之SweepGradient(10)
Android繪圖之RadialGradient 放射漸變(11)
Android繪制之BitmapShader(12)
Android繪圖之ComposeShader,PorterDuff.mode及Xfermode(13)
Android繪圖之drawText,getTextBounds,measureText,FontMetrics,基線(14)
Android繪圖之貝塞爾曲線簡介(15)
Android繪圖之PathMeasure(16)
Android 動態修改漸變 GradientDrawable
D. Android Canvas 方法總結
在自定義 View的時候,我們經常需要繪制一些自己想要的效果。
這里就需要使用Canvas對象。
下面將Canvas對象常用方法做個筆記,方便記憶。
對Canvas的一系列操作,是指對Canvas進行旋轉、平移、縮放等操作。
這些操作可以讓Canvas對象使用起來更加便捷。
Canvas提供了幾個方法,讓我們可以方便的對Canvas的狀態進行更改和還原。
這些方法是: save() 、 restore() 、 restoreToCount(int saveCount) 。
我們在對Canvas進行平移、旋轉、放大等操作時候,可以調用 save() 方法,將當前修改過的Canvas狀態進行保存,調用 restore() 方法後,會將Canvas還原成最近的一個 save() 的狀態。
save() 方法還會有一個返回值,我們也可以調用 restoreToCount(int saveCount) 方法,將這個返回值作為參數傳遞進去,就可以將Canvas還原成某一個特定的 save() 狀態。
E. android 中用畫布旋轉圖片的時候怎麼讓讓他 圍著一個坐標旋轉
方法只有一種。
步驟:
1、畫布平移坐標原點
2、旋轉畫布
示例代碼
java">canvas.save();//保存當前畫布狀態
canvas.translate(x,y);//將坐標中心平移到要圍繞的坐標點x,y
canvas.rotate(90);//旋轉角度,這里比如90度
canvas.restore();//恢復畫圖狀態到保存前
F. canvas中放入一張圖片,但是其中的圖片可以旋轉移動,這是怎麼確定的
使用canvas來實現旋轉效果。
function rotate(obj,arr){
...
// 對現代瀏覽器寫入HTML5的元素進行旋轉: canvas
}else{
var c = document.getElementById('canvas_'+obj);
if(c== null){
img.style.visibility = 'hidden';
img.style.position = 'absolute';
c = document.createElement('canvas');
c.setAttribute("id",'canvas_'+obj);
img.parentNode.appendChild(c);
}
var canvasContext = c.getContext('2d');
switch(n) {
default :
case 0 :
c.setAttribute('width', img.width);
c.setAttribute('height', img.height);
canvasContext.rotate(0 * Math.PI / 180);
canvasContext.drawImage(img, 0, 0);
break;
case 1 :
c.setAttribute('width', img.height);
c.setAttribute('height', img.width);
canvasContext.rotate(90 * Math.PI / 180);
canvasContext.drawImage(img, 0, -img.height);
break;
case 2 :
c.setAttribute('width', img.width);
c.setAttribute('height', img.height);
canvasContext.rotate(180 * Math.PI / 180);
canvasContext.drawImage(img, -img.width, -img.height);
break;
case 3 :
c.setAttribute('width', img.height);
c.setAttribute('height', img.width);
canvasContext.rotate(270 * Math.PI / 180);
canvasContext.drawImage(img, -img.width, 0);
break;
};
}
}
代碼中,創建canvas元素對象,並將圖片賦予canvas對象,當變數n處於不同的狀態(上下左右四個方向)時,使用canvas重新對圖像進行繪制。
G. android openGL es圖形旋轉問題
在android中,要實現動畫效果,要麼通過循環調用canvas.draw系統方法,要麼通過調用opengl es中的GLSurfaceView.Renderer實現方法onDrawFrame方法。 這個方法大體的原理是開起一個線程,在此線程內不斷的調用onDrawFrame,實現效果。
其中gl.glRotatef(angle, x, y, z)的angle是旋過多少度。
H. Android繪圖基礎--Canvas和Drawable
Github鏈接
畫2D圖形有兩種方法:
Canvas實際上是封裝了各種draw方法的類,調用draw方法把圖形繪制到底層的Surface上,即繪制在Window上。
這個例子中構造了兩個Canvas和一個Bitmap,分別調用其draw方法,先是mCanvas往Bitmap里繪制一個方塊,再在onDraw方法內調用canvas.drawBitmap繪制這個方塊。
思考一個問題,為什麼mCanvas需要設置Bitmap?
很簡單,因為它沒有持有一塊內存地址,自然沒法繪制。來看一下draw的起點ViewRootImpl(軟體繪制,不開啟硬體加速下)。
這個通過mSurface.lockCanvas返回的Canvas是View.draw的canvas變數,所以當1,2情況時,Canvas都持有一個Bitmap,指向共享內存里的某一小塊,當調用Canvas.draw方法時就能繪制出東西。但對於自定義Canvas來說並不是,即使設置一個Bitmap和繪制了Bitmap,但不往共享內存上寫,屏幕上是不會顯示的,SurfaceView同理,通過Surface.lockCanvas獲取持有共享內存的Canvas,繪制完畢後調用Surface.unlockCanvasAndPost把繪制內容顯示到surface上並release掉Canvas。
順帶一提Canvas.save和Canvas.restore方法,如下Demo
效果圖如
畫的是三個顏色和旋轉角度都不同的小方形。
步驟1把默認坐標系旋轉20°,畫出第一個藍色的方形,步驟2保存當前的matrix(旋轉了20°),繼續旋轉20°,此時坐標系已經旋轉了40°,畫出第二個黃色的方塊,步驟3,恢復上一步保存的matrix(旋轉了20°),此時坐標系還是旋轉了20°,步驟4,再旋轉40°,此時坐標系旋轉了60°,畫出第三個黑色方塊。
Canvas.save用於保存當前matrix和clip,Canvas.restore用於恢復上次保存的matrix和clip。
Drawable是一個能畫出來的物體的抽象,使用前需要調用setBounds確定位置和大小,通過getIntrinsicHeight和getIntrinsicWidth取到實際大小。Drawable可以有幾種形式存在:Bitmap、Nine Patch、Vector、Shape、Layers等。
從Resource.getDrawable會判斷是否.xml結尾,不是的話走6,7步,如果從xml中讀取,需要getResource.getDrawable -> ResourceImpl.loadDrawableForCookie -> drawable.createFromXml -> DrawableInflater.inflateFromXmlForDensity -> drawable.inflateFromTag
看一下Shape實現類GradientDrawable的inflate實現,讀取各項屬性並賦值,到draw方法。
調用canvas.drawRect把mRect畫出來,而mRect的賦值在ensureValidRect。[圖片上傳失敗...(image-a25af0-1515826613001)]
bounds在哪裡設置的?答案是ImageView.updateDrawable內,會調用Drawable.getIntrinsicHeight賦值(從xml中size屬性讀取),再調用configureBounds -> setBounds,如果使用的不是ImageView,一定要在draw之前 調用setBounds ,否則size就會出錯。
回到loadDrawableForCookie,再看一下6,7步載入圖片的過程,通過AssetManager讀取圖片流數據,通過Drawable.createFromResourceStream這個我們經常使用的方法獲取到Drawable。
取到屏幕密度之後調用BitmapFactory.decodeResourcesStream,計算密度後調用native創建Bitmap,感興趣的同學可以看下更具體的分析文章(如 理解Bitmap )。
本文探究了兩點
Android 7.1.1 源碼
Android 官方文檔, Canvas and Drawable , Drawable 等
I. canvas實現圖片旋轉
canvas的上下文context有個旋轉方法
參數degree是弧度制, 例如30°轉換成30*Math.PI/180
ctx坐標系原點(0,0)在左上方, 坐標方向是y↓→x, rotate之後順時針旋轉, 畫圖的方式也會跟著旋轉, 以順時針旋轉90°為例:
旋轉之前畫圖方式先左後右, 先上後下
旋轉之後先上後下, 先右後左
為了使圖完整的還在ctx裡面, 坐標變成(0, -height), 這樣圖片就實現了順時針旋轉90°