自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

HarmonyOS用Matrix實現(xiàn)各種圖片ScaleType縮放

開發(fā) 前端 OpenHarmony
本文將從零開始實現(xiàn)一個圖片組件,并展示如何使用 Matrix 實現(xiàn)圖片的各種 ScaleType 縮放效果,鴻蒙 Image 組件沒有對外公開 setMatrix 接口,可參考本文,自己實現(xiàn)自繪式 Image 組件。

[[418482]]

想了解更多內(nèi)容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

本文將從零開始實現(xiàn)一個圖片組件,并展示如何使用 Matrix 實現(xiàn)圖片的各種 ScaleType 縮放效果。

背景知識:

Matrix 內(nèi)部通過維護一個 float[9] 的數(shù)組來構(gòu)成 3x3 矩陣的形式,從底層原理來看,所有的變換方法就是更改數(shù)組中某個或某幾個位置的數(shù)值;

Matrix提供了Translate(平移)、Scale(縮放)、Rotate(旋轉(zhuǎn))、Skew(扭曲)四中變換操作,這四種操作實質(zhì)上是調(diào)用了setValues()方法來設(shè)置矩陣數(shù)組來達到變換效果。除Translate(平移)外,Scale(縮放)、Rotate(旋轉(zhuǎn))、Skew(扭曲)都可以圍繞一個中心點來進行,如果不指定,在默認情況下是圍繞(0, 0)來進行相應(yīng)的變換的。

Matrix提供的四種操作,每一種都有pre、set、post三種形式。原因是矩陣乘法不滿足乘法交換律,因此左乘還是右乘最終的效果都不一樣。我們可以把Matrix變換想象成一個隊列,隊列里面包含了若干個變換操作,隊列中每個操作按照先后順序操作變換目標完成變換,pre相當于向隊首增加一個操作,post相當于向隊尾增加一個操作,set相當于清空當前隊列重新設(shè)置。

鴻蒙 Image 組件沒有對外公開 setMatrix 接口,如果項目中需要通過 setMatrix 來控制圖片顯示,可參考本文,自己實現(xiàn)自繪式 Image 組件。

創(chuàng)建圖片組件

先創(chuàng)建一個組件類 MyImageComponent,因為是從零開始,所以我們從 Component 繼承,包含以下三個屬性:

  1. public class MyImageComponent extends Component implements Component.DrawTask {    
  2.     // 圖片資源,從 src 屬性讀取 
  3.     private Element element; 
  4.     // 讀取 scaleType 屬性 
  5.     private ScaleType scaleType = ScaleType.fitCenter; 
  6.     // 用于實現(xiàn) scaleType 的 Matrix  
  7.     private final Matrix matrix = new Matrix(); 
  8.      
  9.     // ...其他構(gòu)造函數(shù)略 
  10.     public MyImageComponent(Context context, AttrSet attrSet, int resId) { 
  11.         super(context, attrSet, resId); 
  12.         init(attrSet); 
  13.     } 

然后執(zhí)行初始化流程:

  1. // 初始化,包括讀取屬性,根據(jù) scaleType 設(shè)置 matrix,添加繪制方法      
  2.    private void init(AttrSet attrSet) { 
  3.        readAttrSet(attrSet);       
  4.        dealScaleType(); 
  5.        addDrawTask(this); 
  6.    } 
  7.  
  8.    // 讀取 xml 屬性,包括 src 和 scaleType 
  9.    private void readAttrSet(AttrSet attrSet) { 
  10.        element = attrSet.getAttr("src").get().getElement(); 
  11.         
  12.        if (attrSet.getAttr("scaleType").isPresent()) { 
  13.            String scaleTypeString = attrSet.getAttr("scaleType").get().getStringValue(); 
  14.            scaleType = Utils.getEnumFromString(ScaleType.class, scaleTypeString, ScaleType.center); 
  15.        } 
  16.    } 
  17.  
  18.    // 根據(jù) scaleType 屬性實現(xiàn)對應(yīng)的縮放效果 
  19.    private void dealScaleType() { 
  20.        switch (scaleType) { 
  21.            default
  22.            case fitCenter: 
  23.                fitCenter(); 
  24.                break; 
  25.            case center: 
  26.                center(); 
  27.                break; 
  28.            case fitXY: 
  29.                fitXY(); 
  30.                break; 
  31.            case fitStart: 
  32.                fitStart(); 
  33.                break; 
  34.            case fitEnd: 
  35.                fitEnd(); 
  36.                break; 
  37.            case centerCrop: 
  38.                centerCrop(); 
  39.                break; 
  40.            case centerInside: 
  41.                centerInside(); 
  42.                break; 
  43.        } 
  44.    } 
  45.  
  46.    private int getDisplayWidth() { 
  47.        return getWidth() - getPaddingLeft() - getPaddingRight(); 
  48.    } 
  49.   
  50.    private int getDisplayHeight() { 
  51.        return getHeight() - getPaddingLeft() - getPaddingRight(); 
  52.    } 
  53.  
  54. private int getElementWidth() { 
  55.        return element.getWidth(); 
  56.    } 
  57.  
  58.    private int getElementHeight() { 
  59.        return element.getHeight(); 
  60.    } 

ScaleType 效果展示和對應(yīng)源碼

以下逐個展示各種 ScaleType 效果及其實現(xiàn)代碼,為方便對比不同大小的圖片的 ScaleType 差異,準備了一大一小兩張圖片。

【中軟國際】HarmonyOS 用 Matrix 實現(xiàn)各種圖片 ScaleType 縮放-鴻蒙HarmonyOS技術(shù)社區(qū)
【中軟國際】HarmonyOS 用 Matrix 實現(xiàn)各種圖片 ScaleType 縮放-鴻蒙HarmonyOS技術(shù)社區(qū)

用于預(yù)覽的 xml 布局代碼如下:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     xmlns:app="http://schemas.ohos.com/apk/res-auto" 
  5.     ohos:height="match_parent" 
  6.     ohos:width="match_parent" 
  7.     ohos:alignment="center" 
  8.     ohos:orientation="vertical"
  9.  
  10.     <com.bm.mycomponent.MyImageComponent 
  11.         ohos:width="200vp" 
  12.         ohos:height="200vp" 
  13.         ohos:background_element="#4682B4" 
  14.         ohos:margin="6vp" 
  15.         app:src="$media:big" 
  16.         app:scaleType="center" 
  17.         /> 
  18.     <com.bm.mycomponent.MyImageComponent 
  19.         ohos:width="200vp" 
  20.         ohos:height="200vp" 
  21.         ohos:margin="6vp" 
  22.         ohos:background_element="#4682B4" 
  23.         app:src="$media:small" 
  24.         app:scaleType="center" 
  25.         /> 
  26.  
  27. </DirectionalLayout> 

以下是各種 scaleType 的效果和源碼:

center

【中軟國際】HarmonyOS 用 Matrix 實現(xiàn)各種圖片 ScaleType 縮放-鴻蒙HarmonyOS技術(shù)社區(qū)
  1. /** 
  2.     * 圖片居中顯示在組件中,不對圖片進行縮放 
  3.     */ 
  4.    private void center() { 
  5.        float wTranslate = (getDisplayWidth() - getElementWidth()) * 0.5f; 
  6.        float hTranslate = (getDisplayHeight() - getElementHeight()) * 0.5f; 
  7.  
  8.        matrix.postTranslate(wTranslate, hTranslate); 
  9.    } 

fitCenter

保持圖片的寬高比,對圖片進行X和Y方向縮放,直到一個方向鋪滿組件,縮放后的圖片居中顯示在組件中。

【中軟國際】HarmonyOS 用 Matrix 實現(xiàn)各種圖片 ScaleType 縮放-鴻蒙HarmonyOS技術(shù)社區(qū)
  1. private void fitCenter() { 
  2.         float wPercent = (float)getDisplayWidth() / (float)getElementWidth(); 
  3.         float hPercent = (float)getDisplayHeight() / (float)getElementHeight(); 
  4.         float minPercent = Math.min(wPercent, hPercent); 
  5.  
  6.         float targetWidth = minPercent * getElementWidth(); 
  7.         float targetHeight = minPercent * getElementHeight(); 
  8.  
  9.         float wTranslate = (getDisplayWidth() - targetWidth) * 0.5f; 
  10.         float hTranslate = (getDisplayHeight() - targetHeight) * 0.5f; 
  11.  
  12.         matrix.setScale(minPercent, minPercent); 
  13.         matrix.postTranslate(wTranslate, hTranslate); 
  14.     } 

fitXY

對X和Y方向獨立縮放,直到圖片鋪滿組件。這種方式可能會改變圖片原本的寬高比,導致圖片拉伸變形。

【中軟國際】HarmonyOS 用 Matrix 實現(xiàn)各種圖片 ScaleType 縮放-鴻蒙HarmonyOS技術(shù)社區(qū)
  1. private void fitXY(){ 
  2.        float wPercent = (float)getDisplayWidth() / (float)getElementWidth(); 
  3.        float hPercent = (float)getDisplayHeight() / (float)getElementHeight(); 
  4.        matrix.setScale(wPercent, hPercent); 
  5.    } 

fitStart

保持圖片的寬高比,對圖片進行X和Y方向縮放,直到一個方向鋪滿組件,縮放后的圖片與組件左上角對齊進行顯示。

【中軟國際】HarmonyOS 用 Matrix 實現(xiàn)各種圖片 ScaleType 縮放-鴻蒙HarmonyOS技術(shù)社區(qū)
  1. private void fitStart() { 
  2.       float wPercent = (float)getDisplayWidth() / (float)getElementWidth(); 
  3.       float hPercent = (float)getDisplayHeight() / (float)getElementHeight(); 
  4.       float minPercent = Math.min(wPercent, hPercent); 
  5.        
  6.       matrix.setScale(minPercent, minPercent); 
  7.   } 

fitEnd

保持圖片的寬高比,對圖片進行X和Y方向縮放,直到一個方向鋪滿組件,縮放后的圖片與組件右下角對齊進行顯示。

【中軟國際】HarmonyOS 用 Matrix 實現(xiàn)各種圖片 ScaleType 縮放-鴻蒙HarmonyOS技術(shù)社區(qū)
  1. private void fitEnd() { 
  2.      float wPercent = (float)getDisplayWidth() / (float)getElementWidth(); 
  3.      float hPercent = (float)getDisplayHeight() / (float)getElementHeight(); 
  4.      float minPercent = Math.min(wPercent, hPercent); 
  5.  
  6.      float targetWidth = minPercent * getElementWidth(); 
  7.      float targetHeight = minPercent * getElementHeight(); 
  8.      float wTranslate = getDisplayWidth() - targetWidth; 
  9.      float hTranslate = getDisplayHeight() - targetHeight; 
  10.  
  11.      matrix.setScale(minPercent, minPercent); 
  12.      matrix.postTranslate(wTranslate, hTranslate); 
  13.  } 

centerCrop

保持圖片的寬高比,等比例對圖片進行X和Y方向縮放,直到每個方向都大于等于組件對應(yīng)的尺寸,縮放后的圖片居中顯示在組件中,超出部分做裁剪處理。

【中軟國際】HarmonyOS 用 Matrix 實現(xiàn)各種圖片 ScaleType 縮放-鴻蒙HarmonyOS技術(shù)社區(qū)
  1. private void centerCrop() { 
  2.       float scale; 
  3.       float dx; 
  4.       float dy; 
  5.  
  6.       if (getElementWidth() * getDisplayHeight() > getDisplayWidth() * getElementHeight()) { 
  7.           scale = (float)getDisplayHeight() / (float)getElementHeight(); 
  8.           dx = (getDisplayWidth() - getElementWidth() * scale) * 0.5f; 
  9.           dy = 0f; 
  10.       } else { 
  11.           scale = (float)getDisplayWidth() / (float)getElementWidth(); 
  12.           dx = 0f; 
  13.           dy = (getDisplayHeight() - getElementHeight() * scale) * 0.5f; 
  14.       } 
  15.  
  16.       matrix.setScale(scale, scale); 
  17.       matrix.postTranslate(dx + 0.5f, dy + 0.5f); 
  18.   } 

centerInside

如果圖片寬度<= 組件寬度&&圖片高度<= 組件高度,不執(zhí)行縮放,居中顯示在組件中。其余情況按 fitCenter 處理。

【中軟國際】HarmonyOS 用 Matrix 實現(xiàn)各種圖片 ScaleType 縮放-鴻蒙HarmonyOS技術(shù)社區(qū)
  1. private void centerInside() { 
  2.        if (getElementWidth() <= getDisplayWidth() && getElementHeight() <= getElementHeight()){ 
  3.            float wTranslate = (getDisplayWidth() - getElementWidth()) * 0.5f; 
  4.            float hTranslate = (getDisplayHeight() - getElementHeight()) * 0.5f;             
  5.            matrix.setTranslate(wTranslate, hTranslate); 
  6.        } else { 
  7.            fitCenter(); 
  8.        } 
  9.    } 

繪制圖片組件

關(guān)鍵是這句 canvas.concat(matrix)

  1. @Override 
  2.     public void onDraw(Component component, Canvas canvas) { 
  3.         // 以下是關(guān)鍵代碼,將 matrix 應(yīng)用到 canvas 
  4.         canvas.concat(matrix);         
  5.         // 將圖片繪制到 canvas 
  6.         element.drawToCanvas(canvas); 
  7.     } 

項目地址:my-image-component

想了解更多內(nèi)容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2023-05-11 07:38:51

2011-09-01 10:20:18

VMworld虛擬化惠普

2012-05-23 15:45:13

JavaScript

2011-05-12 11:28:20

按比例縮放

2013-05-27 09:52:35

Android開發(fā)移動開發(fā)移動應(yīng)用

2013-05-27 10:01:06

Android開發(fā)Android應(yīng)用縮放圖片

2023-09-08 09:12:57

內(nèi)存緩存圖像

2023-10-27 08:53:13

Python驗證碼圖片識別

2009-12-21 14:31:39

Fedora core

2021-08-25 09:38:16

鴻蒙HarmonyOS應(yīng)用

2023-09-28 16:15:01

Element XMatrix 2.0

2023-10-19 10:12:34

圖形編輯器開發(fā)縮放圖形

2009-05-08 09:17:48

動態(tài)數(shù)據(jù)庫圖片

2015-06-25 09:42:47

swift蘋果開源

2010-06-21 17:08:10

Java框架ScalaSpring

2017-04-27 21:00:33

Android滑動分析

2021-02-25 15:14:12

鴻蒙HarmonyOS應(yīng)用開發(fā)

2011-03-18 19:05:31

QQQtWidget

2025-02-10 04:01:00

WebSpring工具

2014-12-31 16:48:43

Touch touchevent多點觸摸
點贊
收藏

51CTO技術(shù)棧公眾號