|
詳細については、以下をご覧ください。 51CTOとHuaweiが共同で構築したHarmonyOSテクノロジーコミュニティ。 https://harmonyos..com 序文Androidプラットフォームベースの画像切り抜きコンポーネント crop_image_layout (https://github.com/yulu/crop-image-layout) がHarmonyOSに移行およびリファクタリングされました。コードはオープンソース化されており (https://gitee.com/isrc_ohos/crop_image_layout_ohos)、既に多くのスターやフォークを獲得しています。皆様のダウンロード、ご利用、そして貴重なフィードバックをお待ちしております。 背景`crop_image_layout_ohos`コンポーネントは、画像の回転とカスタムトリミングを可能にし、元のサイズに関係なく、画像を最適なサイズで表示します。さらに、ユーザーインターフェースはシンプルで使いやすく、開発者が容易に適応・最適化できるため、アプリケーションのリッチさと使いやすさを向上させます。 コンポーネント効果表示このコンポーネントを使用すると、画像、切り取りボックス、ボタンを操作して、画像の一部を切り取って表示することができます。コンポーネントの機能は図1に示されています。 図 1. crop_image_layout_ohos コンポーネントの実行効果。 対応するスクリーンショットには、提供される主な機能が表示されます。
サンプル分析1. コンポーネントの全体的な使用フロー 図2 コンポーネント使用フロー図 コンポーネントの使い方を紹介する前に、まず crop_image_layout_ohos コンポーネントの機能を構成する 3 つの重要な部分を紹介します。 - クロッピングフレーム:画像のクロッピング領域を定義します。 - トリミングされた画像: コンポーネントにインポートされ、トリミングされる予定の画像を指します。 - コンポーネント領域: コンポーネントの位置を示します。 コンポーネントを使用するプロセスは、次のように要約できます。まず、クロッピング ボックスの位置 (座標) を設定し、次にクロッピング ボックスの座標データを切り抜いた画像に追加し、最後にクロッピング ボックスと切り抜いた画像をコンポーネント領域に追加します。 このプロセスにおいて、コンポーネントは切り抜かれた画像と切り抜きボックスのサイズに応じた適応的な表示効果も実現します。その具体的な原理については、ライブラリ分析のセクションで説明します。 2. コンポーネントを使用するための具体的な手順 以下では、6 つのステップで構成される crop_image_layout_ohos コンポーネントの具体的な使用方法について説明します。 ステップ 1. XML ファイルに EditPhotoView コントロールを追加します。 ステップ 2. 必要なクラスをインポートし、クラス オブジェクトをインスタンス化します。 ステップ3. 切り抜き画像に切り抜き枠の座標を設定します。 ステップ 4. 切り取った画像と切り取りボックスをレイアウトに追加します。 ステップ 5. 切り取りボックスの左上隅と右下隅の座標を表示します。 ステップ 6. イベント リスナーを設定します。 (1) XMLファイルにEditPhotoViewコントロールを追加する XMLファイルに、crop_image_layout_ohosのコンポーネント領域を表示するためのEditPhotoViewコントロール(com.huawei.croplayout.EditPhotoView)を追加します。画像に示すように、切り取り枠の角と端の色、および切り取り画像の選択されていない部分の影の色を設定します。 図3 属性設定の概略図
(2)必要なクラスをインポートし、クラスオブジェクトをインスタンス化する MainAbilitySlice クラスの onStart() メソッドで、それぞれ onBoxChangedListeneron、EditPhotoView、EdittableImage、ScalableBox クラスをインポートします。
`EditPhotoView` オブジェクトと `Text` オブジェクトを作成し、それぞれ `crop_image_layout_ohos` のコンポーネント領域と、クロッピングボックスの座標を表示するテキストコントロールをバインドします。図 1 に示すクロッピング後の画像を格納する `image` という名前の `EdittableImage` オブジェクトをインスタンス化し、コンポーネントにインポートします。クロッピングボックスの座標を格納する `ScalableBox` 型の `List` オブジェクトを作成し、`boxes` という名前を付けます。左上隅の座標 (25, 180)、右下隅の座標 (640, 880) を持つ新しいクロッピングボックスオブジェクトをインスタンス化し、`add()` メソッドを使用して `boxes` オブジェクトに追加します。
(3)切り取り画像に切り取り枠座標を設定する。 `setBoxes()` メソッドは、`boxes` プロパティ内のクロッピング ボックスの座標をクロッピング イメージに設定し、クロッピング ボックスの位置をクロッピング イメージに対して相対的に設定しています。
(4)切り取った画像と切り取りボックスをレイアウトに追加します。 intView() メソッドを呼び出して、切り取られた画像と切り取りボックスのビューを作成し、コンポーネント レイアウトに追加して表示します。
(5)切り取り枠の左上隅と右下隅の座標を表示します。 ScalableBox オブジェクト activeBox を再宣言して、クリッピング ボックスの座標を動的に取得し、Text を使用してインターフェイスに表示します。
(6)リスナーイベントを設定する コンポーネント領域のリスナーイベント コンポーネントエリアオブジェクトimageViewにリスナーイベントを設定します。切り取りボックスの位置が変更されると、その座標をテキストオブジェクトboxTextに設定して表示します。
回転ボタンの「回転」イベントリスナー rotateButton という名前の Button オブジェクトを宣言し、それを "rotate_button" コントロールにバインドします。クリックリスナーを設定します。ボタンがクリックされたときに、コンポーネントの imageView オブジェクトを介して rotateImageView() メソッドを呼び出し、画像をトリミングして右に 90° 回転させる効果を実現します。
切り取りボタンのイベントリスナー cropButton という名前の Button オブジェクトを宣言し、「crop_button」コントロールにバインドしてクリックリスナーを設定します。ボタンがクリックされると、cropOriginalImage() メソッドを呼び出して切り取った画像を取得し、PixelMap オブジェクトに保存します。Intent を使用して 2 番目の画面に移動し、切り取った画像をパラメータとして渡して 2 番目の画面に表示します。
ライブラリ分析
1. クリッピングフレームを設定する(サイズをインスタンス化する) 図4. カットフレーム座標の模式図 サンプル解析で説明したように、左上隅の座標が (25, 180)、右下隅の座標が (640, 880) である新しくインスタンス化されたクロッピングボックスを `boxes` オブジェクトに追加するには、`add()` メソッドを呼び出す必要があります。左上隅の座標は図 4 の (X1, Y1) に、右上隅の座標は図 4 の (X2, Y2) にそれぞれ対応します。クロッピングボックスの対角線上にこれらの 2 つの点を設定することで、そのサイズと位置を一意に決定できます。
インスタンス化プロセスでは、ScalableBox クラスのコンストラクターを通じて、切り取りボックスの左上隅と右下隅の座標を設定する必要があります。
2. 切り抜き画像に切り抜き枠の座標を設定します。 クロップボックスリストの最初のオブジェクト `boxes` を取得します。これは、先ほど設定した対角座標を持つクロップボックスデータであり、クロップ後の画像に追加します。これは、`EditableImage` クラスの `setBoxes()` メソッドを使用して実現されます。 このメソッドでは、クロッピングボックスオブジェクトのリスト「boxes」が空でなく、そのサイズが0より大きい場合、「boxes」は「EditableImage」クラスのメンバー変数「originalBoxes」に割り当てられ、すべてのクロッピングボックスオブジェクトのデータが格納されます。このクラスの別のメンバー変数「copyofActiveBox」がインスタンス化され、選択されたクロッピングボックスの2つの角の座標値が格納されます。「activeBoxIdx」は、「boxes」に格納されているクロッピングボックス座標のインデックスを参照します。「List」はユーザー用に複数のクロッピングボックス座標を予約できますが、このコンポーネントはインデックス0のクロッピングボックス座標のみを使用します。
3. 切り取った画像と切り取りボックスをレイアウトに追加します。 この機能は、`EditPhotoView` クラスの `initView()` メソッドによって実装されています。まず、`EditPhotoView` オブジェクトの作成時に渡されたクロッピング枠のサイズ、角の寸法、および色属性に基づいて、クロッピング枠ビューを表示するための `SelectionView` クラスがインスタンス化されます。次に、渡されたクロッピング画像に基づいて、クロッピング画像ビューを表示するための `Image` オブジェクトがインスタンス化されます。最後に、`SelectionView` オブジェクトと `Image` オブジェクトの両方のレイアウトが親コンポーネントに従うように設定され、両方がクロッピングコンポーネント領域のレイアウトに追加されて、クロッピング枠とクロッピング画像が表示されます。 切り取られた画像の表示領域のサイズは setViewSize() メソッドを使用して設定され、切り取られた画像のビットマップ形式は setPixelMap() を使用して設定され、画像のスケーリング モードは setScaleMode() を使用して中央スケーリングに設定され、切り取られた画像と切り取りボックスのサイズは setBoxSize() を使用して設定されます。
(1)切り取った画像を、切り取った画像表示エリアに収める 切り抜いた画像の表示領域はコンポーネント領域と同じサイズであり、切り抜いた画像のサイズは固定されていないため、切り抜いた画像を表示領域に表示するときにサイズを調整する必要があります。 前述の機能は、`EditableImage` クラスの `getFitSize()` メソッドによって提供され、`setBoxSize()` メソッド内で呼び出されます。このメソッドは、切り抜かれた画像を表示領域に合わせて調整し、調整後の画像サイズを返します。これは、切り抜かれた画像の表示領域内に画像がより適切に表示されるようにするためであり、極端に大きい画像や極端に小さい画像が、表示に最適なサイズに調整されます。その原理は図 5 に示されています。 図 5. 画像サイズ適応原理の概略図 (左: ratio > viewRatio、右はその逆)。 まず、元の切り取られた画像 (つまり、ピンクの四角形) の幅と高さの比率 (比率、つまり、a/b) と、コンポーネント領域 (つまり、黄色の四角形) の幅と高さの比率 (viewRatio、つまり、c/d) を計算します。 元の切り抜き画像のアスペクト比が切り抜き画像表示領域のアスペクト比よりも大きい場合(図5の左側の画像)、元の切り抜き画像の幅「a」が切り抜き画像表示領域の幅「c」(青い四角形)の長さと同じになるまで、元の切り抜き画像を最大限に拡大することができます。この場合、比率で拡大した後の元の切り抜き画像の高さ「b」の長さは、切り抜き画像表示領域の高さ「d」よりも必ず短くなります。したがって、拡大後の高さの長さは、画像の幅の拡大率に基づいて計算できます。 切り取った元の画像のアスペクト比が切り取った画像の表示領域のアスペクト比よりも小さい場合(図5の右側)、前の場合と同じロジックが適用されます。つまり、切り取った元の画像の高さbが切り取った画像の表示領域の高さd(青い四角形)の長さと同じになるまで、切り取った元の画像を最大限に拡大することができます。この場合、比率で拡大した後の切り取った元の画像の幅aの長さは、切り取った画像の表示領域の幅cよりも必ず小さくなります。したがって、拡大後の幅の長さは、画像の高さの拡大率に基づいて計算できます。 計算後、拡大された画像の幅と高さは整数配列 `fitSize[]` に格納されます。上記の例では、元の切り抜き画像のサイズが切り抜き画像の表示領域よりも小さいと仮定していますが、その逆も同様です。
(2)切り取り枠と画像を調整します。 切り抜き枠は切り抜かれた画像と同じ表示比率を維持する必要があるため、切り抜き枠を切り抜かれた画像に合わせて調整する必要があります。 上記の機能は、`SelectionView` クラスの `setBoxsize()` メソッドによって実現されます。このメソッドは、調整された画像の幅と高さを取得し、それらの寸法とクロッピングボックスの幅と高さを使用して `originX` と `originY` を計算し、次に `setDisplayBoxes()` メソッドを呼び出して、調整されたクロッピングボックスの座標を設定します。
`setDisplayBoxes()` メソッドの中核部分は、画像のスケーリング比率に基づいて、適応後のクロップボックスの対角線上の2点の座標を計算することです。まず、スケーリング前後の画像の幅の比率(scale、つまり c/a)を計算します。次に、インスタンス化時に設定された左上隅のクロップボックスの初期サイズ x1 にスケーリング比率 `scale` を掛けて、適応後の x 座標を取得します。これを先ほど計算した `originX` に加えると、適応後のクロップボックスの左上隅の x 座標 `scaleX1` が得られます。同様に、右下隅の x 座標 `scaleX2`、左上隅の垂直座標 `scaleY1`、右下隅の垂直座標 `scaleY2` も計算されます。
詳細については、以下をご覧ください。 51CTOとHuaweiが共同で構築したHarmonyOSテクノロジーコミュニティ。 https://harmonyos..com |