<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] # 1. 前言 在之前我們已經用過很多次關于Canvas的一些常用方法。需要注意的是: * 每次調用 drawXXX 系列函數來繪圖時,都會產生一個全新的 Canvas 透明圖層。 * 如果在調用 drawXXX 系列函數前,調用平移、旋轉等函數對 Canvas 進行了操作, 那么這個操作是不可逆的。每次產生的畫布的最新位置都是這些操作后的位置。 * 在 Canvas 圖層與屏幕合成時,超出屏幕范圍的圖像是不會顯示出來的。 # 2. 畫布裁剪 裁剪畫布是指利用 clip 系列函數,通過與 Rect、Path、Region 取交、并、差等集合運算 來獲得最新的畫布形狀。除調用 save()、restore()函數以外,這個操作是不可逆的,**一旦 Canvas 被裁剪,就不能恢復。** **注意**:在使用裁剪畫布系列函數時,需要禁用硬件加速功能。 比如: ``` protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.clipRect(new Rect(100, 100, 200, 200)); canvas.drawColor(Color.GREEN); } ``` 先把背景色涂成紅色,顯示在屏幕上;然后裁剪畫布;最后將最新的畫布涂成綠色。可 見,綠色部分只有一小塊,而不再是整個屏幕了。注意到前面提到,**一旦 Canvas 被裁剪,就不能恢復。**也就是之后的繪制操作都將只會在裁剪得到的矩形畫布中進行。 # 3. 畫布的保存和恢復 前面介紹的所有對畫布的操作都是不可逆的,這會造成很多麻煩。比如,為了實現一些 效果而不得不對畫布進行操作,但操作完了,畫布狀態也改變了,這會嚴重影響到后面的畫 圖操作。故而在Android中提供了save()和 restore()函數來保存當前畫布狀態。即: * save():每次調用 save()函數,都會先**保存當前畫布的狀態(但不會新建畫布),然后將其放入特定的棧**中,該方法返回一個int類型的ID,可以用來記錄在棧中的記錄,可以指定恢復畫布狀態。 * restore():每次調用 restore()函數,都會**把棧中頂層的畫布狀態取出來,并按照這個狀 態恢復當前的畫布,然后在這個畫布上作畫**。 * saveLayer(RectF bounds, Paint paint, int saveFlags):保存當前畫布狀態到特定棧,并新建一個空白畫布。該方法返回一個int類型的ID,可以用來記錄在棧中的記錄,可以指定恢復畫布狀態。 * restoreToCount(int saveCount),表示一直退棧,直到把指定索引的畫布信息退出來,之后的棧最上層的畫布信息將作為最新的畫布。 ## 3.1 saveFlags 也就是標識。 ![](https://img.kancloud.cn/88/13/8813ea897aa1453eb2aacee41b35b714_1025x486.png) ## 3.1 saveLayer()函數時的繪圖流程 在調用 saveLayer()函數時,會生成一塊全新的畫布(Bitmap),這塊畫布的大小就是我們 指定的所要保存區域的大小。新生成的畫布是全透明的,在調用 saveLayer()函數后所有的繪 圖操作都是在這塊畫布上進行的。 ### 3.1.1 Q1:為什么在使用圖像混合模式的時候,通常需要在saveLayer和restoreToCount兩個函數之間? 因為圖像混合模式是就近的進行計算的,而前面提到過,每次調用 canvas.drawXXX 系列函數,都會生成一個透明圖層來專門繪制這個圖形,也就是如果我們繪制了兩個圖像。在《Android自定義控件開發入門與實戰》一書中給了圖示,很直觀,比如: ![](https://img.kancloud.cn/d4/14/d41443eaa8d3cc1b5a5e538c17f1afdf_653x367.png) 在通過使用圖像混合模式的時候,就近的兩個圖像進行疊加,也就是上圖中的源圖像和目標圖像進行運算,得到最終的顯示狀態。對應的代碼: ~~~ protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GREEN); // 保存當前圖層,新建一個圖層 int layerID = canvas.saveLayer(0, 0, width * 2, height * 2, mPaint, Canvas.ALL_SAVE_FLAG); // 目標圖像 canvas.drawBitmap(dstBmp, 0, 0, mPaint); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); // 源圖像 canvas.drawBitmap(srcBmp, width / 2, height / 2, mPaint); // 清空圖像混合模式 mPaint.setXfermode(null); // 恢復保存的圖層狀態 canvas.restoreToCount(layerID); } ~~~ 注釋:目標圖像在下,需要先繪制。 如果將saveLayer這個代碼注釋,也就是不再新建一個圖層。在去掉 saveLayer()函數后,就不會新建畫布了。也就是目標將繪制在原始畫布上,對應的代碼: ~~~ protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GREEN); // 目標圖像 canvas.drawBitmap(dstBmp, 0, 0, mPaint); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); // 源圖像 canvas.drawBitmap(srcBmp, width / 2, height / 2, mPaint); mPaint.setXfermode(null); } ~~~ 圖示: ![](https://img.kancloud.cn/7f/07/7f078e58902951bd7473cc9647ff1dc3_643x319.png) 那么效果就是這兩個圖層的圖像混合運算結果。 ### 3.1.2 Q2:關于Bitmap的內存問題 Bitmap 是位圖,也就是由一個個像素點組成的。一張位圖所占用的內存計算為: > 圖片長度(px)× 圖片寬度(px)× 一個像素點占用的字節數。 存儲一個像素點所使用的字節數是用枚舉類型 Bitmap.Config 中的各個參數來 表示的。比如,Bitmap.Config.ARGB\_8888。也就是8*4=32位,一個像素點對應4個字節。RGB\_565:表示 16 位 RGB 位圖。 在《Android自定義控件開發入門與實戰》一書中提到: ![](https://img.kancloud.cn/5c/51/5c51df9b8d3edb0519559f6564ec87b7_1031x332.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看