1

私のアプリケーションでは、1 つのメイン ビュー (その UIGraphicsGetCurrentContext() を使用) と他のいくつかの CGContextRef キャンバスがあります。それらはすべて同じサイズ、画面のサイズです-倍率はありません。

セカンダリ キャンバスで描画し、最後にセカンダリ キャンバスで CGBitmapContextCreateImage を使用し、メイン キャンバスで描画するために CGContextDrawImage を使用します。

Retina ディスプレイでは結果が悪く、すべての線がピクセル化されて見えます。Retina ディスプレイでの描画はどのように処理すればよいですか?

以下は、コンテキストをメイン コンテキストに描画するために使用するコードです。

void CocoaGraphicsContext::drawContext(GraphicsContext* context, double x, double y, Box* cropBox, Matrix3D* matrix)
{
    CGAffineTransform matInverted;

    if (matrix != NULL)
    {
        CGAffineTransform transMat = CGAffineTransformMake(matrix->vx1, matrix->vy1, matrix->vx2, matrix->vy2, matrix->tx, matrix->ty);
        matInverted = CGAffineTransformInvert(transMat);

        CGContextConcatCTM(_cgContext, transMat);
    }

    CGImageRef cgImage = CGBitmapContextCreateImage(((CocoaGraphicsContext*)context)->cgContext());

    CGContextSaveGState(_cgContext);
    CGContextSetInterpolationQuality(_cgContext, kCGInterpolationNone);

    bool shouldCrop = ((cropBox != NULL) && (cropBox->valid()));

    if (shouldCrop)
    {
        CGContextClipToRect(_cgContext, CGRectMake(cropBox->x(), cropBox->y(), cropBox->width(), cropBox->height()));
    }

    CGContextDrawImage(_cgContext, CGRectMake(x, y, context->width(), context->height()), cgImage);

    CGContextRestoreGState(_cgContext);

    CGImageRelease(cgImage);

    if (matrix != NULL)
    {
        CGContextConcatCTM(_cgContext, matInverted);
    }
}

メイン コンテキストは、UIView クラスから UIGraphicsGetCurrentContext() を使用して取得されます。

---- EDITED --- 初期化コード:

void CocoaBitmapContext::init(double width, double height, unsigned int* data)
{
    int bytesPerRow = width * 2  * VT_BITMAP_BYTES_PER_PIXEL;

    if (data == NULL)
    {
        _dataOwner = true;
        _data = (unsigned int*)malloc(bytesPerRow * height * 2);
    }
    else
    {
        _dataOwner = false;
        _data = data;
    }

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    _cgContext = CGBitmapContextCreate(_data,
                                       width * 2,
                                       height * 2,
                                       VT_BITMAP_BITS_PER_COMPONENT,
                                       bytesPerRow,
                                       colorSpace,
                                       kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);

    CGContextConcatCTM(_cgContext, CGAffineTransformMakeScale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale));

    CGContextSetShouldAntialias(_cgContext, false);
    CGContextSetRGBStrokeColor(_cgContext, 0.0, 0.0, 0.0, 0.0);

    CGColorSpaceRelease(colorSpace);
}
4

1 に答える 1

4

ビットマップのサイズはピクセル単位で指定されますが、画面上のサイズはポイント単位です。を使用して画面の倍率を取得できます[UIScreen mainScreen].scale。これは、1 つの点に含まれるピクセルの数です。Retina ディスプレイを搭載したデバイスの場合、この値は 2 になります。その倍率でキャンバスのサイズをスケーリングする必要があります。また、コンテキストを作成した直後にスケール変換を連結する必要があります。画像を描画するときは、引き続き画面の境界を宛先の四角形として使用する必要があります (スケール変換がスケーリングを処理します)。

CGSize canvasSize = [UIScreen mainScreen].bounds.size;
CGFloat scale = [UIScreen mainScreen].scale;
canvasSize.width *= scale;
canvasSize.height *= scale;

UIGraphicsBeginImageContext(canvasSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextConcatCTM(context, CGAffineTransformMakeScale(scale, scale));
...
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

画像ビューで表示する場合は、画像ビューが画面全体に表示されcontentModeUIViewContentModeScaleToFill.

于 2013-07-14T09:06:19.263 に答える