iOSはresizableImageWithCapInsetsを完全に理解しています



Ios Thoroughly Understand Resizableimagewithcapinsets



Androidの画面適応に携わったことのある人なら誰でも、.9pngを聞いたことがあるはずです。これは、さまざまな画面で画像が歪むことなく引き伸ばされるという問題を解決するための画像形式です。 .9png形式の画像を使用して、角が丸いボタン、矢印が付いたダイアログボックスなど、引き伸ばされた領域と引き伸ばされない領域を指定できます。丸みを帯びた角または引き伸ばされていない矢印を指定できますが、引き伸ばされた領域のみを繰り返すことができます。エリア、.9pngを参照してください

.9pngはhttp://isux.tencent.com/android-ui-9-png.htmlを書きました

なに、Androidはとても背が高いのですか?実際、iOSバージョン5.0以降では、同様の機能であるUIImageも提供されます。



resizableImageWithCapInsetsを作成しました

メソッド、iOS6.0以降、拡張バージョンが追加されました

resizableImageWithCapInsets:resizingMode:を作成しました

違いは、iOS6がresizingModeを追加して、画像の処理にタイリングとストレッチのどちらを使用するかを指定することです。



  • パラメータの説明
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode

capInsets:引き伸ばすことができる領域を指定します

resizingMode:処理モードを指定します-ストレッチまたはタイル

なんてこったい?分かりませんか? ?心配しないで、ゆっくり聞いてください



  • コードの説明

ダイアログ画像をフォローすると

丸みを帯びた角と矢印を残し、画像の幅と高さを2倍にしたい

まず第一に [マーク 男]丸みを帯びた角の位置を見てみましょう



境界を知って、コーディングを始めました。元の画像のサイズは170X50であることに注意してください。ここでは、拡大画像の効果を確認するために、_tileImgView(UIImageView)のサイズを固定の340X100に設定しました。

UIImage *img = [UIImage imageNamed:@'msg.jpg'] UIEdgeInsets tileSets = {.left = 10, .top = 17, .right = 10, .bottom = 10} UIImage *tileImage = [img resizableImageWithCapInsets:tileSets resizingMode:UIImageResizingModeTile] _tileImgView.image = tileImage

効果を見てみましょう

さて、角の丸みは問題ありませんが、待ってください、なぜ3本の矢があり、瞬間があるのでしょうか?

言うまでもなく、問題はtileSets(ストレッチ可能な領域)にあるはずです。では、ストレッチ可能な領域とは正確には何ですか?



上の写真に示すように、影付きの部分の長方形の領域ですか?いいえ、絶対にありません。これが事実である場合、私たちは

画像処理は完璧になり、3本の矢はありません。それで、それは何ですか?実際、Androidを参照してください

.9png、水平ストレッチ領域と垂直領域の2つの部分に分かれています。

垂直領域= [上、下]

水平領域= [左、右]

詳細は以下のとおりです。

水平領域:画像をX方向に拡大する必要がある場合は、[左、右]の間の領域を使用して、拡大する必要のある領域を埋める必要があります。左は

左の境界線からの距離、右は右の境界線からの距離を表します。これら2つの線の間の領域は、伸ばす必要のある余分な領域を埋めるために使用されます。





垂直方向に塗りつぶされた領域:画像をY方向に引き伸ばす必要がある場合は、[上、下]の間の領域を使用して引き伸ばす必要のある領域を塗りつぶす必要があります。上は上境界からの距離を表し、下は上境界からの距離を表します。下限からの距離。 2本の線の間の領域は、伸ばす必要のある余分な領域を埋めるために使用されます



したがって、縦方向を50から100に変更すると、上図に示すように、引き伸ばされた領域が長方形のストリップであるため、縦方向のパフォーマンスは完璧です。

水平領域を分析してみましょう。伸縮可能な領域のサイズは170-10(左)-10(右)= 150で、伸縮できない領域は左の境界線の10ピクセルの丸い角と10ピクセルの丸いです。右の境界線の角。

iOSのresizableImageWithCapInsetsは、描画やその他のストレッチを次のように処理します。両端の非ストレッチ領域を維持し、中央のストレッチ可能領域でストレッチ可能領域を埋めます。



左右に10ピクセルを保持し、中央の残りの320ピクセルは伸縮可能な領域で埋められます。タイル方式を使用しているため、中央は170(元のサイズ)-10(左)-10(右)= 150の伸縮可能な領域を使用して残りの320ピクセルを埋めます

したがって、最終的な効果は150 + 150 + 20 = 320であり、正確に3つの矢印が表示されます。



上記は概略図ですので、元の縮尺は無視してください。

tileSetsを次の形式に変更するとどうなりますか?

UIImage *img = [UIImage imageNamed:@'msg.jpg'] UIEdgeInsets tileSets = {.left = 20, .top = 17, .right = 140, .bottom = 10} UIImage *tileImage = [img resizableImageWithCapInsets:tileSets resizingMode:UIImageResizingModeTile] _tileImgView.image = tileImage



ストレッチ可能な領域はわずか10ピクセル(170-20-140)で、これは矢印の幅だけで、ストレッチされる領域は180(340-20-140)です。

この方法で計算すると、プログラムの結果は180/10 = 18になり、18個の矢印効果が含まれます。



原理を知った後、最初の質問に戻り、丸い角と矢印を維持するのはどうですか?矢印が伸縮可能な領域にない限り

コードは以下のように表示されます

UIImage *img = [UIImage imageNamed:@'msg.jpg'] UIEdgeInsets tileSets = {.left = 40, .top = 17, .right = 77, .bottom = 10} UIImage *tileImage = [img resizableImageWithCapInsets:tileSets resizingMode:UIImageResizingModeTile] _tileImgView.image = tileImage


効果を見てみましょう



それは完璧ですが、待ってください、次のコードが同じ効果を達成できるようです:

UIEdgeInsets tileSets = {.left = 40, .top = 17, .right = 77, .bottom = 10} UIEdgeInsets tileSets = {.left = 40, .top = 17, .right = 129, .bottom = 10} UIEdgeInsets tileSets = {.left = 32, .top = 17, .right = 10, .bottom = 10}

私は何をすべきですか、私は何をすべきですか?慌てる必要はありません。Appleのドキュメントを確認してください。

Appleのドキュメントには、サイズ変更可能な領域の幅または高さが1ピクセルの場合、つまり、水平方向にサイズ変更可能な領域の幅が1ピクセル、垂直方向にサイズ変更可能な領域の高さが1ピクセル、または画像の中央領域が1 x 1ピクセルの場合(iOS) 1ピクセルの領域を引き伸ばして画像を描画します。このモードは、最速のパフォーマンスを提供します(ゼロ以外のキャップインセットの場合)。

おそらくそれはあなたが採用した場合を意味しますUIImageResizingModeStretch(ストレッチモード)、次に、ストレッチされた領域のピクセルの長さまたは幅を保存して、パフォーマンスが最適になるようにするのが最善です。タイルモードについては、説明がありません。

最後に、知りたい友達が教えてくれますUIImageResizingModeTile((タイリングモード)、ストレッチエリアはどのように定義されていますか?最高のパフォーマンスを発揮するピクセルですか?

ソースコードは次のとおりです。