23

これが簡単な図面です

    

- (void)drawRect:(CGRect)rect
{
    //vertical line with 1 px stroking
    UIBezierPath *vertLine = [[UIBezierPath alloc] init];
    [vertLine moveToPoint:CGPointMake(20.0, 10.0)];
    [vertLine addLineToPoint:CGPointMake(20.0, 400.0)];
    vertLine.lineWidth = 1.0;
    [[UIColor blackColor] setStroke];
    [vertLine stroke];

    //vertical rectangle 1px width 
    UIBezierPath *vertRect= [UIBezierPath bezierPathWithRect:CGRectMake(40.0, 10.0, 1.0, 390.0)];
    [[UIColor blackColor] setFill];
    [vertRect fill];

}

非網膜3GSおよびシミュレーターでは、最初の線はぼやけて1ピクセルより広く見えますが、2番目の線は鮮明です。

残念ながら、私はiPhone4も新しいiPadもテストする必要はありませんが、網膜シミュレーターでは両方の線が同じように見えます。

質問:非網膜デバイスと網膜デバイスで同じ結果を得るには、ストロークではなく長方形が唯一の方法ですか?

4

2 に答える 2

53

長方形の内側を塗りつぶしていますが、中心から線をなでています。どちらの場合も座標(長方形の角と線の開始座標と終了座標)は整数値(分数なし)として定義されているため、座標は正確な点の境界上にあります。

線のポイントについて話すときは、画面上のポイントと混同しないように、上記の「座標」と言いました。同じ理由で、「ピクセル境界」ではなく「ポイント境界」とも言いました。iOSは、その座標とすべてのポイントを、ピクセルではなく「ポイント」と呼ばれるもので定義します。ポイントは、解像度に依存しない測定です。網膜デバイスと非網膜デバイスの両方が画面上に同じ数のポイントを持っています、それはそれらが実際のピクセルの異なる数に対応しているということだけです。

角が点の境界にある長方形を塗りつぶすのと比較して、点の境界にある線をなでるのを見てみましょう(あなたの質問のように):

以下の図では、非網膜スクリーンと網膜スクリーンの両方で、黒で線を描き、長方形をオレンジで塗りつぶしています。また、線と長方形の輪郭を青で示しています。どちらの場合も、その解像度のポイントのサイズを確認し、実際のピクセルグリッドと比較できます。

非網膜の場合、中心から1ポイントの線(この場合は1ピクセルの線幅に対応)で線をストロークしようとすると、上部のピクセルの半分とピクセルの半分が塗りつぶされることがわかります。下。ピクセルは半分しか塗りつぶされていないため、これらのピクセルの不透明度は50%です。これにより、(白い背景の)明るい色になります。上と下の両方のピクセルがパーティで塗りつぶされているため、ストロークすると上と下の両方のピクセルが塗りつぶされます。これにより、線の幅が1ピクセルではなく2ピクセルのように見えます。

これは、内側が塗りつぶされている長方形とすばやく比較できます。

非網膜

Retina画面の同じケースは異なって見えます。この場合、ポイントのサイズは同じですが、1ではなく4ピクセルで構成されます。今回は、線をなでるときに、線の上の半分のポイントと線の下の半分のポイントがピクセルの行を完全に埋めます。画面の解像度が高いため、上下に表示されます。これは、線が1ポイント幅であるかのように見え、色が完全に不透明に見えることを意味します。

また、塗りつぶされた長方形が同じように見えることもわかります。

網膜


これを修正するには、ラインのポイントを半分のピクセルに配置します。低解像度のデバイスで中心から線を引くと、線は上に0.5ポイント、下に0.5ポイント伸びます。線の中心がポイントの中心にあるため、これは、ストロークされた線が完全にピクセル内にあり、線がシャープに見えることを意味します。これを行っても、半分のポイントを下(または上)に移動するため、網膜線に影響はありません。それでも、上下のピクセルを完全に塗りつぶすことを意味します。

下の図(網膜の場合)では、ポイントグリッドとピクセルグリッドの両方を示しています。

ハーフピクセル非網膜 ハーフピクセル網膜

于 2012-06-24T10:22:35.193 に答える
2

ストロークと塗りつぶしで異なる結果が得られる理由は、引数の解釈が異なるためです。

ストロークは、座標の両側に線の幅の半分を追加します。つまり、ポイントは20.0で、線の幅は1pxです。結果は、理論的には(19.5-20.5)の間に1ピクセルの黒い線になります。デバイス画面には非整数ピクセルがないため、(19-21)の間の2ピクセルの灰色/ぼやけた線に変換されます。これを回避するには、各座標を0.5で合計する必要があります(CGPointMake(20.5、10.5)のように)。これにより、幅がピクセル間で分割されなくなります。

ただし、塗りつぶしの引数は、塗りつぶす領域の境界を設定するために使用されます。CGRectMake(40.0、10.0、1.0、390.0)は、(40〜41)の間の領域を意味します。その結果、ぼやけて見えるピクセルに小数部分が落ちることはありません。

于 2014-04-24T08:40:19.597 に答える