1

私はCGLayersを使用して、Photoshopエアブラシに似た「ペイント」技法を実装していますが、奇妙なことに遭遇しました。透明度を使用して領域を上塗りすると、色が完全な強度に達することはありません(アルファ値が0.5未満の場合)。私のアプリケーションは、不透明度がエッジで落ちる円形の「エアブラシ」パターンを使用していますが、半透明の白い正方形を使用するだけで問題を再現しました。不透明度レベルが0.5未満の場合、上塗りされた領域がソースレイヤーの真っ白に達することはありません。気づかなかったかもしれませんが、絵の結果をマスクとして使っているので、真っ白になれないと問題が発生します。ここで何が起こっているのかアイデアはありますか?iOSSDK5.1をターゲットにします。

以下は、黒い背景の上に半透明の正方形を何度も描いた後の結果の色です。

opacity color
------  -----
1.0     255
0.9     255
0.8     255
0.7     255
0.6     255
0.5     255
0.4     254
0.3     253
0.2     252
0.1     247

問題を示す簡略化されたコード:

- (void)drawRect:(CGRect)rect
{
    CGContextRef viewContext = UIGraphicsGetCurrentContext();

    // Create grey gradient to compare final blend color
    CGRect lineRect = CGRectMake(20, 20, 1, 400);
    float greyLevel = 1.0;
    for(int i=0;i<728;i++)
    {
        CGContextSetRGBFillColor(viewContext, greyLevel, greyLevel, greyLevel, 1);
        CGContextFillRect(viewContext, lineRect);
        lineRect.origin.x += 1;
        greyLevel -= 0.0001;
    }

    // Create semi-transparent white square
    CGSize whiteSquareSize = CGSizeMake(40, 40);
    CGLayerRef whiteSquareLayer = CGLayerCreateWithContext (viewContext, whiteSquareSize, NULL);
    CGContextRef whiteSquareContext = CGLayerGetContext(whiteSquareLayer);
    CGContextSetAlpha(whiteSquareContext, 1.0f); // just to make sure
    CGContextSetRGBFillColor(whiteSquareContext, 1, 1, 1, 0.3); // ??? color never reaches pure white if alpha < 0.5
    CGRect whiteSquareRect = CGRectMake(0, 0, whiteSquareSize.width, whiteSquareSize.height);
    CGContextFillRect(whiteSquareContext, whiteSquareRect);

    // "Paint" with layer a bazillion times
    CGContextSetBlendMode(viewContext, kCGBlendModeNormal); // just to make sure
    CGContextSetAlpha(viewContext, 1.0); // just to make sure
    for(int strokeNum=0;strokeNum<100;strokeNum++)
    {
        CGPoint drawPoint = CGPointMake(0, 400);
        for(int x=0;x<730;x++)
        {
            CGContextDrawLayerAtPoint(viewContext, drawPoint, whiteSquareLayer);
            drawPoint.x++;
        }
    }
}
4

0 に答える 0