0

円形グラデーションをレンダリングし、パン ジェスチャ レコグナイザーを使用して、指でそれをスイープできるメソッドを作成しました。

現在のタッチ位置でピクセルを取得しており、その色を取得したいと考えています。

つまり、グラデーションの上を移動している間、色の値は常に更新される必要があります。

私は次のコードを使用しています:

- (IBAction)handlePan:(UIPanGestureRecognizer *)sender {


    CGPoint translation = [sender translationInView:iv];
    [sender setTranslation:CGPointZero inView:self.view];

    CGPoint center = sender.view.center;
    center.x += translation.x;
    center.y += translation.y;

    sender.view.center = center;
    CGPoint colorPoint = [sender.view.superview convertPoint:center toView:iv];

   [sender setTranslation:CGPointMake(0, 0) inView:self.view];





    CGImageRef image = img.CGImage;
    NSUInteger width = CGImageGetWidth(image);
    NSUInteger height = CGImageGetHeight(image);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    char *rawData = malloc(height * width * 4);
    int bytesPerPixel = 4;
    int bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(
                                                 rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big
                                                 );
    CGContextSetBlendMode(context, kCGBlendModeCopy);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
    CGContextRelease(context);
    int byteIndex = (bytesPerRow * colorPoint.y) + colorPoint.x * bytesPerPixel;
    unsigned char red = rawData[byteIndex];
    unsigned char green = rawData[byteIndex+1];
    unsigned char blue = rawData[byteIndex+2];


    UIColor *hauptfarbe = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
    ch.backgroundColor = hauptfarbe;





    NSLog(@"Color value - R : %i G : %i : B %i",red, green, blue);







}

これは意図したとおりに機能せず、間違った色が表示され、一部の色 (赤など) がまったく表示されません

編集:担当者が少ないため、まだ写真を追加できません。グラデーションをレンダリングするためのコードを追加します

コード :

- (void)viewDidLoad
{
    [super viewDidLoad];
    CGSize size = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height);
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), YES, 0.0);
    [[UIColor whiteColor] setFill];
    UIRectFill(CGRectMake(0, 0, size.width, size.height));

    int sectors = 180;
    float radius = MIN(size.width, size.height)/2;
    float angle = 2 * M_PI/sectors;
    UIBezierPath *bezierPath;
    for ( int i = 0; i < sectors; i++)
    {
        CGPoint center = CGPointMake((size.width/2), (size.height/2));
        bezierPath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:i * angle endAngle:(i + 1) * angle clockwise:YES];
        [bezierPath addLineToPoint:center];
        [bezierPath closePath];
        UIColor *color = [UIColor colorWithHue:((float)i)/sectors saturation:1. brightness:1. alpha:1];
        [color setFill];
        [color setStroke];
        [bezierPath fill];
        [bezierPath stroke];
    }
    img = UIGraphicsGetImageFromCurrentImageContext();
    iv = [[UIImageView alloc] initWithImage:img];
    [self.view addSubview:iv];
    [self.view addSubview:ch];

}
4

1 に答える 1

0

ここでの最初の問題は、計算方法ですcolorPoint。彼らは今のように、colorPoint常にビューの中心点になります。このhandlePan:メソッドは、ビュー内の最後のタッチのポイントを取得する必要があります。

- (IBAction)handlePan:(UIPanGestureRecognizer *)sender
{
    if (sender.numberOfTouches)
    {
        CGPoint lastPoint = [sender locationOfTouch: sender.numberOfTouches - 1 inView: sender.view];
        NSLog(@"lastPoint: %@", NSStringFromCGPoint(lastPoint));
    }
}

そこから、画像をビットマップ コンテキストにブリットしてからその時点で読み戻そうとするのではなく、画像の作成に使用したのと同じ数学的プロセスを使用してポイントの色を計算することをお勧めします。最初の場所。あなたが現在行っている方法は、CPU + メモリをより集中的に使用することになります。

編集:これが私が思いついたものです。わたしにはできる。Xcode の Single View Application テンプレートから開始し、投稿したコードを使用して、ViewController.m に次のコードを作成しました。

@implementation ViewController
{
    UIImage* img;
    UIImageView* iv;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    CGSize size = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height);
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), YES, 0.0);
    [[UIColor whiteColor] setFill];
    UIRectFill(CGRectMake(0, 0, size.width, size.height));

    int sectors = 180;
    float radius = MIN(size.width, size.height)/2;
    float angle = 2 * M_PI/sectors;
    UIBezierPath *bezierPath;
    for ( int i = 0; i < sectors; i++)
    {
        CGPoint center = CGPointMake((size.width/2), (size.height/2));
        bezierPath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:i * angle endAngle:(i + 1) * angle clockwise:YES];
        [bezierPath addLineToPoint:center];
        [bezierPath closePath];
        UIColor *color = [UIColor colorWithHue:((float)i)/sectors saturation:1. brightness:1. alpha:1];
        [color setFill];
        [color setStroke];
        [bezierPath fill];
        [bezierPath stroke];
    }
    img = UIGraphicsGetImageFromCurrentImageContext();
    iv = [[UIImageView alloc] initWithImage:img];
    [self.view addSubview:iv];
    colorView = [[UIView alloc] init];
    colorView.frame = CGRectMake(CGRectGetMaxX(bounds) - 25, CGRectGetMaxY(bounds) - 25, 20, 20);
    [self.view addSubview:colorView];

    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]
                                          initWithTarget:self action:@selector(handlePan:)];

    [self.view addGestureRecognizer: panGesture];    
}

- (IBAction)handlePan:(UIPanGestureRecognizer *)sender
{
    if (sender.numberOfTouches)
    {
        CGPoint lastPoint = [sender locationOfTouch: sender.numberOfTouches - 1 inView: sender.view];
        CGRect bounds = self.view.bounds;
        CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
        CGPoint delta = CGPointMake(lastPoint.x - center.x,  lastPoint.y - center.y);
        CGFloat angle = (delta.y == 0 ? delta.x >= 0 ? 0 : M_PI : atan2(delta.y, delta.x));
        angle = fmod(angle,  M_PI * 2.0);
        angle += angle >= 0 ? 0 : M_PI * 2.0;
        UIColor *color = [UIColor colorWithHue: angle / (M_PI * 2.0) saturation:1. brightness:1. alpha:1];
        colorView.backgroundColor = color;
        CGFloat r,g,b,a;
        if ([color getRed: &r green: &g blue:&b alpha: &a])
        {
            NSLog(@"Color value - R : %g G : %g : B %g", r, g, b);
        }
    }
}

@end

グラデーション上で指をドラッグすると、指の位置に対応する RGB 値を含むメッセージがコンソールに安定して送信されます。右下の小さなビューに最後の色を表示するコードも追加しました。また、ビットマップ コンテキストも使用しません。お役に立てれば。

于 2013-07-08T11:14:10.907 に答える