最後に、minificationFilter プロパティと magnificationFilter プロパティについて説明します。一般に、画像を表示するときは、画像を正しく表示する必要があります (つまり、画像を正しい比率と正しい 1:1 ピクセルで画面に表示する)。その理由は次のとおりです:
ピクセルを圧縮したり引き伸ばしたりせずに、可能な限り最高の画質を表示できます。 保存する必要があるのはそれだけであるため、メモリを有効に活用できます。 最高のパフォーマンスを得るために、CPU は追加の計算を必要としません。しかし、場合によっては、非実物大の画像を表示することが実際に必要な効果となることがあります。たとえば、アバターや写真のサムネイル、またはドラッグして取り消すことができる大きな写真などです。このような場合、同じ画像の異なるサイズに対して異なる画像を保存することは現実的ではありません。
画像をさまざまなサイズで表示する必要がある場合、ストレッチ フィルターと呼ばれるアルゴリズムが機能します。元の画像のピクセルに作用し、画面上に表示するために必要に応じて新しいピクセルを生成します。
実際、画像サイズを再描画するための統一された一般的なアルゴリズムはありません。それは、拡大する必要があるコンテンツ、ズームインまたはズームアウトの必要性などによって異なります。 CALayer は、この目的のために 3 つのストレッチ フィルタリング メソッドを提供します。
kCAFilterLinear kCAFilterNearest kCAFilterTrilinear縮小 (画像を縮小) および拡大 (画像を拡大) このフィルタは、バイリニア フィルタリング アルゴリズムを使用します。ほとんどの状況。バイリニア フィルタリング アルゴリズムは、複数のピクセルをサンプリングすることによって最終的に新しい値を生成し、その結果、スムーズでパフォーマンスの高いストレッチが得られます。ただし、倍率を大きくすると画像がぼやけてしまいます。
kCAFilterTrilinear と kCAFilterLinear は非常に似ています。ほとんどの場合、この 2 つに違いは見られません。ただし、バイリニア フィルタリング アルゴリズムと比較して、トライリニア フィルタリング アルゴリズムは複数のサイズのピクチャ (マルチマップとも呼ばれます) を保存し、それらを 3 次元でサンプリングして、大きなピクチャと小さなピクチャのストレージを組み合わせて最終結果を取得します。
この方法の利点は、アルゴリズムが既に最終サイズに近い一連の画像から、つまり多くのピクセルを同時にサンプリングすることなく、望ましい結果を取得できることです。これにより、パフォーマンスが向上するだけでなく、低い確率で丸め誤差によって引き起こされるサンプリング失敗の問題も回避されます
図 4.14 大きな画像の場合、バイリニア フィルタリングとトリリニア フィルタリングのパフォーマンスが向上します
kCAFilterNearest は、より任意の方法です。名前からわかるように、このアルゴリズム (最近接フィルタリングとも呼ばれます) は、他の色に関係なく、最も近い単一ピクセルをサンプリングします。これは非常に高速で、画像がぼやけることはありません。ただし、最も明白な影響は、圧縮された画像が悪化することであり、拡大すると画像がブロック状になったり、ひどいモザイクが表示されたりします。
図 4.15 スラッシュのない小さな画像の場合、最近のフィルタリング アルゴリズムの方がはるかに優れています
一般に、特に明らかな違いがあり、スラッシュがほとんどない小さな画像または大きな画像の場合、最近のフィルタリング アルゴリズムは、より良い結果を提供するためにこの独特の品質が保持されます。 。しかし、ほとんどの画像、特に斜線や曲線の輪郭が多い画像では、最近のフィルタリング アルゴリズムでは結果が悪化します。言い換えれば、線形フィルタリングは形状を保存しますが、最近接フィルタリングはピクセルの差を保存します。
実験してみましょう。第 3 章で時計プロジェクトを変更し、LCD スタイルのデジタル ディスプレイを使用してみましょう。シンプルなピクセル フォント (ベクトル グラフィックスではなく、ピクセルを使用して文字を形成するフォント) を使用してデジタル ディスプレイを作成し、それらを画像として保存し、第 2 章で紹介したステッチング技術を使用して表示します (図 4.16)。
図 4.16 スプライシング技術を使用して表示された単純な LCD デジタル スタイルのピクセル フォント
Interface Builder に 6 つのビュー (時間、分、秒ごとに 2 つ) を配置しました。 図 4.17 は、これら 6 つのビューがどのように Interface Builder に配置されるかを示しています。 。それぞれにフェードアウトしたアウトレット オブジェクトを使用するのは多すぎるため、IBOutletCollection オブジェクトを使用してコントローラーに接続し、ビューに配列としてアクセスできるようにします。リスト 4.6 はコードの実装です。
リスト 4.6 は LCD スタイルの時計を示しています
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
@interface ViewController ()
@property (非アトミック、強力) IBOutletCollection(UIView) NSArray *digitViews; @property (非アトミック、弱い) NSTimer *タイマー; ?? @end
@implementation ViewController
- (void)viewDidLoad { [super viewDidLoad]; // スプライトシート画像を取得 UIImage *digitals = [UIImage imageNamed:@"Digits.png"];
//桁ビューを設定します for (UIView *view in self.digitViews) { //内容を設定します view.layer.contents = (__bridge id)digits.CGImage; view.layer.contentsRect = CGRectMake(0, 0, 0.1, 1.0); view.layer.contentsGravity = kCAGravityResizeAspect; }
//タイマー開始 self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(tick) userInfo:nil repeats:YES];
//初期時計時間を設定します [self tick]; }
- (void)setDigit:(NSInteger)digit forView:(UIView *)view { //contentsRect を調整して正しい数字を選択します view.layer.contentsRect = CGRectMake(桁 * 0.1 、0、0.1、1.0); }
- (無効)ティック { //時間を時、分、秒に変換します NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar]; NSUInteger units = NSHourCalendarUnit | NS分カレンダー単位 | NSSecondCalendarUnit; ? NSDateComponents *components = [カレンダーコンポーネント:単位fromDate:[NSDate date]];
//時間を設定する [self setDigit:components.hour / 10 forView:self.digitViews[0]]; [self setDigit:components.hour % 10 forView:self.digitViews[1]];
//分を設定します [self setDigit:components. minutes / 10 forView:self.digitViews[2]]; [self setDigit:components. minutes % 10 forView:self.digitViews[3]];
//秒を設定 [self setDigit:components.second / 10 forView:self.digitViews[4]]; [self setDigit:components.second % 10 forView:self.digitViews[5]]; } @end |
図 4.18 のように、このようにして効果が得られましたが、図は模倣されたシートです。承認された kCAFilterLinear 選択は私は望めませんでした。図 4.18 一つのパターンの時間、承認された kCAFilterLinear によって引き起こされました
能像を実現するために、図 4.19 の中那样、私は次のように追加する必要があります:
1
view.layer .magnificationFilter = kCAFilterNearest; |
図 4.19 最近のフィルタリングを設定した後の表示のクリア グループの透明度UIView には、ビューの透明度を決定する alpha と呼ばれるプロパティがあります。 CALayer には不透明度と呼ばれる同等のプロパティがあり、どちらもサブレベルに影響します。つまり、レイヤーに不透明度属性を設定すると、そのすべてのサブレイヤーがこれの影響を受けます。 iOS では、スペースのアルファ値を 0.5 (50%) に設定して、スペースが使用できないように見せるのが一般的です。スタンドアロン ビューの場合は問題ありませんが、コントロールにサブビューがある場合は少し奇妙になります。図 4.20 は、UILabel が埋め込まれたカスタム UIButton を示しています。左側は不透明なボタンで、右側は 50% 透明です。内側のラベルの輪郭がボタンの背景と一致していないことがわかります。
図 4.20 右側のフェード ボタンでは、内側のラベルがはっきりと見えます これは、透明度 50% のレイヤーを表示すると、レイヤーの各ピクセルが通常になります。独自の色を表示し、残りの半分はレイヤーの下の色を表示します。これは通常の透明度です。ただし、レイヤーに 50% の透明度も表示するサブレイヤーが含まれている場合、表示されるビューの 50% はサブビューから、25% はレイヤー自体の色から、残りの 25% は背景色から得られます。 この例では、ボタンと絵文字の両方の背景が白です。どちらも 50% の可視性を持っていますが、合計の可視性は 75% であるため、ラベルが配置されている領域は周囲の部分ほど透明に見えません。そのため、サブビューが強調表示されて表示効果がひどいようです。 理想的には、レイヤーの透明度を設定するときは、そのレイヤーに含まれるレイヤー ツリー全体が全体として透明になるようにする必要があります。 Info.plist ファイルの UIViewGroupOpacity を YES に設定することでこの効果を実現できますが、この設定はアプリケーションに影響し、アプリ全体に悪影響を及ぼす可能性があります。 UIViewGroupOpacity が設定されていない場合、iOS 6 およびそれ以前のバージョンではデフォルトで NO になります (後のバージョンではいくつかの変更がある可能性があります)。 もう 1 つの方法は、CALayer の shouldRasterize というプロパティを設定して (リスト 4.7 を参照)、グループ透明度の効果を実現することです。これが YES に設定されている場合、レイヤーとそのサブレイヤーは全体に透明度を適用する前に統合されます。これにより、透明度の混合の問題は発生しません (図 4.21 を参照)。 shouldRasterize プロパティを有効にするには、レイヤーの rasterizationScale プロパティを設定します。デフォルトでは、すべてのレイヤーのストレッチは 1.0 であるため、 shouldRasterize プロパティを使用する場合は、Retina 画面でのピクセル化の問題を防ぐために、画面に一致するように rasterizationScale プロパティを設定する必要があります。 shouldRasterize と UIViewGroupOpacity を一緒に使用すると、パフォーマンスの問題が発生します (第 12 章「速度」と第 15 章「レイヤーのパフォーマンス」で紹介します) が、パフォーマンスの衝突は局所的に発生します (翻訳者注: この文は再翻訳する必要があります) )。 リスト 4.7 shouldRasterize 属性を使用してグループの透明性の問題を解決する
図4.21 修正後の画像 总结この章では、コードを使用して画像レイヤーに適用できるいくつかのビデオ効果を紹介します。コーナー、エフェクト、およびモンゴルパネルも承ります。 |