顯示具有 androidGraphic 標籤的文章。 顯示所有文章
顯示具有 androidGraphic 標籤的文章。 顯示所有文章

2013年5月12日 星期日

[Graphic] Vector Drawables

Drawable 分為兩類:


Bitmap Drawables
  • Bitmap files, ex:
    • PNG which are rendered as images by the OS.
    • 9-patch bitmaps which enable the OS to anamorphically distort the image to fit a particular region.
Vector Drawables
  • Consist of XML files which contain some basic vector drawing command which the OS renders dynamically at runtime.
  • 缺點:
    • Require more processing power to render,particularly gradients; 
    • The drawing primitives are not as flexible as those in your favorite image manipulation software.


兩種差異是單一的 vector drawable 在不同顯示規格下的縮放表現較好(a single vector drawable will scale much better on a variety of different display types)。


* Reference
- Vector Drawables – part 1

2012年6月15日 星期五

[Graphic] Gif format

GIF 的版本有分
  • GIF 87a: 不會動的
  • GIF 89a: 此版本的格式才支援動態


不會動的一定是 87a 格式

或是可以使用 Ultra Edit 查看 header

可分辨是何種格式的


* Reference
- wiki GIF

2012年5月1日 星期二

[AndroidGraphic] Canvas and Drawables

Drawing 2D graphics:
  • 由 layout 來畫。適用於不是太複雜、不需動態更動、像遊戲需要要求效率的圖 。
  • 直接用 Canvas 來畫出你的圖。適用於會規律性更新內容的圖。
    • You personally call the appropriate class's onDraw() method (passing it your Canvas), or one of the Canvas draw...() methods (like drawPicture()).
    • Doing in which thread:
      • In UI thread: call invalidate() and then handle the onDraw() callback.
      • In a separate thread: wherein you manage a SurfaceView and perform draws to the Canvas as fast as your thread is capable (you do not need to request invalidate()).

Draw with a Canvas
  • A Canvas works for you as a pretense, or interface, to the actual surface upon which your graphics will be drawn — it holds all of your "draw" calls. 
  • 有兩種使用方式
    • On a View (extends View)
      • Using within the onDraw() callback method, the Canvas is provided for you and you need only place your drawing calls upon it. 
    • On a SurfaceView
      • You can also acquire a Canvas from SurfaceHolder.lockCanvas(), when dealing with a SurfaceView object.
  • If you need to create a new Canvas, then you must define the Bitmap upon which drawing will actually be performed. 
  • The Bitmap is always required for a Canvas.
  • You can set up a new Canvas like this:
// 在此 Canvas 上所畫的內容,會以傳入的 Bitmap 為底。
Bitmap b = Bitmap.createBitmap(100,100,Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);

// 然後可以藉由 Canvas.drawBitmap() 得到所畫的 Bitmap。
// Drawable has its own draw() method that takes your Canvas as an argument.
drawable.draw(canvas); // 將 drawable 畫到 canvas 上。
It's recommended that you ultimately draw your final graphics through a Canvas offered to you by View.onDraw() or SurfaceHolder.lockCanvas().


On a View
如果 view 中沒有含大量處理過程或是會一直更新畫面(frame-rate speed, ex: chess game, a snake game, or another slowly-animated application),那麼可以繼承 View 客制自己的 view,在 View.onDraw() 中利用 Android Framework 傳入的 Canvas 畫圖。
  • 當要畫出你的 View 時,Android Framework 會呼叫 View.onDraw() ,但 The Android framework 只會在需要時去呼叫 onDraw(),不過你也可以藉 invalidate() 去觸發此呼叫,你的 view 會被重繪。
  • invalidate() 只能在 UI/main thread 中被呼叫,若是要在 non-UI thread 中呼叫,改使用 postInvalidate().


On a SurfaceView (android.view.SurfaceView)
  • The SurfaceView is a special subclass of View that offers a dedicated drawing surface within the View hierarchy.
  • 可以控制它的格式和大小。
  • SurfaceView 會負責把它的 surface 放在螢幕上正確的位置。
Purpose:
  • 在 View hierarchy 還沒準備好前,便可以在 secondary thread 中利用 SurfaceView 和它的 Canvas 繪畫且在 secondary thread rendering 它到 screen。
    • To offer this drawing surface to an application's secondary thread, so that the application isn't required to wait until the system's View hierarchy is ready to draw.
    • To provide a surface in which a secondary thread can render into the screen. 
  • Instead, a secondary thread that has reference to a SurfaceView can draw to its own Canvas at its own pace.
Process:
  • 藉 SurfaceHolder interface 的 getHolder() 可以取得和它相關的 surface。
  • 當 SurfaceView's window 為可視時,Surface 會被建立。
  • Implement surfaceCreated(SurfaceHolder) and surfaceDestroyed(SurfaceHolder) 就可以看到當 window 顯示與隱藏時,Surface 也被建立與摧毀。
To be aware of some threading semantics:
  • All SurfaceView and SurfaceHolder.Callback methods will be called from the thread running the SurfaceView's window (typically the main thread of the application).
    • They thus need to correctly synchronize with any state that is also touched by the drawing thread.
  • You must ensure that the drawing thread only touches the underlying Surface while it is valid -- between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed().

How to use?
  • Create a new class that extends SurfaceView.
  • The class should also implement SurfaceHolder.Callback.
  • This subclass is an interface that will notify you with information about the underlying Surface, such as when it is created, changed, or destroyed.
  • Inside your SurfaceView class is also a good place to define your secondary Thread class, which will perform all the drawing procedures to your Canvas.

Note:
  • Instead of handling the Surface object directly, you should handle it via a SurfaceHolder.
  • When your SurfaceView is initialized, get the SurfaceHolder by calling getHolder().
  • Notify the SurfaceHolder that you'd like to receive SurfaceHolder callbacks (from SurfaceHolder.Callback) by calling addCallback() (pass it this).
  • Override each of the SurfaceHolder.Callback methods inside your SurfaceView class.
  • On each pass you retrieve the Canvas from the SurfaceHolder, the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the entire surface. 
    • For example, you can clear the previous state of the Canvas by filling in a color with drawColor() or setting a background image with drawBitmap(). Otherwise, you will see traces of the drawings you previously performed.


Drawables
  • A Drawable is a general abstraction for "something that can be drawn."
  • In application, 一個 drawable 只會擁有一份,狀態是共享,因此不管怎麼取得擁有,修改了其中的狀態,則原圖(其他 instance) 也會改變。
    • Each unique resource in your project can maintain only one state, no matter how many different objects you may instantiate for it. 
    • For example, if you instantiate two Drawable objects from the same image resource, then change a property (such as the alpha) for one of the Drawables, then it will also affect the other. So when dealing with multiple instances of an image resource, instead of directly transforming the Drawable, you should perform a tween animation.
  • 可以使用 mutate() 取得原圖,這樣這個就不會被改變到。

There are three ways to define and instantiate a Drawable:
  • Using an image saved in your project resources;
    • Supported file types are PNG (preferred), JPG (acceptable) and GIF (discouraged).
    • 放在 res/drawable/ 下的圖片,在 build 的過程,aapt 會自動以失真最少的方式壓縮圖片簡省空間。
    • 若是圖片不想被壓縮則可以放在 res/raw/ 下。
  • Using an XML file that defines the Drawable properties;
    • This philosophy caries over from Views to Drawables. 
    • If there is a Drawable object that you'd like to create, which is not initially dependent on variables defined by your application code or user interaction, then defining the Drawable in XML is a good option. 
    • Even if you expect your Drawable to change its properties during the user's experience with your application, you should consider defining the object in XML, as you can always modify properties once it is instantiated.
    • Any Drawable subclass that supports the inflate() method can be defined in XML and instantiated by your application.
  • Using the normal class constructors.


Shape Drawable
  • When you want to dynamically draw some two-dimensional graphics, a ShapeDrawable object will probably suit your needs.
  • With a ShapeDrawable, you can programmatically draw primitive shapes and style them in any way imaginable.


* Reference
- Canvas and Drawables | Android Developers

2012年4月28日 星期六

[AndroidGraphic] Bitmap and Drawable

// drawable 轉換為 bitmap: 利用canvas物件來達成。
Bitmap drawableToBitmap(Drawable drawable) { 
    Bitmap.Config c = drawable.getOpacity() != PixelFormat.OPAQUE ? 
        Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
    Bitmap bitmap = Bitmap.createBitmap( 
        drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), c);
    Canvas canvas = new Canvas(bitmap); 
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), 
    drawable.getIntrinsicHeight()); 
    drawable.draw(canvas); 
    return bitmap;
}

Bitmap bitmap = ((BitmapDrawable) iconDrawable).getBitmap();
new BitmapDrawable(Bitmap.createScaledBitmap(bitmap, 128, 128, true))


// bitmap 轉換為 drawable: 利用BitmapDrawable直接轉換。
Drawable bitmapToDrawable(Bitmap bitmap) {
    Drawable drawable = new BitmapDrawable(bitmap);return drawable;
}


* Reference
- Camangi 市集 - 關發商資訊

2012年3月25日 星期日

[AndroidGraphic] Glossaries

  • Camera ( android.graphics.Camera )
    • 是一個可以讓你將 2D 物件在 3D 空間中移動,
    • 並將在其移動後的結果,畫在螢幕上的類別。
    • 其實是個 helper class。他提供一些 APIs ,讓你控制要如何在 3D 空間中移動,
    • 最後再產生出合適的 Matrix ,讓你套用到 Canvas 的座標體系上。
  • Bitmap
    • 可以來自 local resource/asset,也可以在程序中建立。
    • 功能相當於圖片的儲存空間。
  • Canvas
    • 和 Bitmap 緊密連繫。
    • 把 Bitmap 比喻為内容的話,Canvas 就是提供了眾多方法操作 Bitamp 的平台 (畫布)。
  • Paint
    • 和 Canvas 緊密連繫。
    • 是"畫板"上的筆刷工具,也用於設置 View 上的樣式。
  • Drawable
    • 如果說 Bitmap, Canvas and Paint 是看不見地在内存中畫圖,那麼 Drawable 就是把他們繪圖结果表現出来的接口。
    • 擁有多個子類,例如:BitmapDrawable, ShapeDrawable, LayerDrawable 等。


* Reference
- android.graphics.Camera, 3D 的效果 - Java-Jinguo - ITeye技术网站
- Android入门第十四篇之画图 - hellogv的专栏 - 博客频道 - CSDN.NET

2012年3月24日 星期六

[AndroidGraphic] ImageView

在 Android 中不允許 ImageView 在產生後,態態修改其長度和寬度,

所以要實現圖片放大缩小的功能,必須將原來的 ImageView 移除,

重新產生一个新的 ImageView,並且指定圖片來源给它,再放入Layout中。


設為 wrap_content 的 ImageView 在 onCreate 的時候就確定了 ImageView 的寬高,

並且给這個 ImageView 分配了内存空間。這個時候我們可以看成是静態設置。

可以理解成已經分配過的就不允许再操作了。


* Reference
- 用Matrix放大了图片,Imageview的大小却没改变